C Симметричный потоковый шифр - PullRequest
5 голосов
/ 22 декабря 2008

У кого-нибудь есть хорошая реализация потокового шифра, написанного на чистом переносимом C? Я не очень обеспокоен силой шифра в данный момент, потому что это только для подтверждения концепции, но скорость будет важна. Я думал о том, чтобы просто Xor'ing с константой, если я не могу найти приличный потоковый шифр.

Ответы [ 7 ]

6 голосов
/ 22 декабря 2008

EDIT (2018): используйте NaCl или libsodium или TweetNaCl , если вы ищете меньший код. Они обеспечивают надежное шифрование и должны быть намного быстрее, чем RC4.

RC4 - очень простой для реализации алгоритм.

Посмотрите Реализация Стерлинга Камдена или Реализация Адама Бека .

4 голосов
/ 23 декабря 2008

См. Проект ECRYPT eStream . Это серьезные хардкорные криптографические алгоритмы, оцененные экспертами по безопасности. Насколько я знаю, все алгоритмы-кандидаты должны были включать реализацию на чистом C (не на C ++).

edit: Самое замечательное в этом веб-сайте то, что он углубляется в различные алгоритмы, включая их известные недостатки, а также включает тесты производительности .

2 голосов
/ 22 декабря 2008

Для чистого приложения POC вы можете быстро бросить ROT13 на место. http://en.wikipedia.org/wiki/ROT13

Однако я очень сомневаюсь в том, чтобы сделать предложение, поскольку слишком часто простой код POC, который должен быть заменен позже, никогда не бывает ...

1 голос
/ 22 декабря 2008

Вот очень базовая реализация потокового шифра на C. Это , а не , любыми средствами, предназначенными для обеспечения безопасности. Это просто иллюстрирует, как выполнить основные необходимые шаги.

Настоящее волшебство должно быть сделано в функции CycleKey, которая генерирует новые значения ключей при прохождении каждого куска данных через поток шифрования.

Этот пример шифрует по одному char за раз. Вам придется расширить концепцию на более крупные порции данных, чтобы шифрование было практически безопасным. Еще раз, я сделал это просто для иллюстрации основных шагов.

Удачи в проекте!

#include <stdio.h>

char staticKey;

void CycleKey(char data)
{
    /* this is where the real magic should occur */
    /* this code does *not* do a good job of it. */

    staticKey += data;

    if (staticKey & 0x80)
    {
        staticKey ^= 0xD8;
    }
    else
    {
        staticKey += 0x8B;
    }
}

void ResetCipher(const char * key)
{
    staticKey = 0;

    while (*key)
    {
        CycleKey(*key);
        key++;
    }
}

void Encrypt(const char * plaintext, char * encrypted)
{
    while (*plaintext)
    {
        *encrypted = *plaintext + staticKey;

        CycleKey(*encrypted);

        encrypted++;
        plaintext++;
    }

    *encrypted = '\0';
}

void Decrypt(char * plaintext, const char * encrypted)
{
    while (*encrypted)
    {
        *plaintext = *encrypted - staticKey;

        CycleKey(*encrypted);

        plaintext++;
        encrypted++;
    }

    *plaintext = '\0';
}

int main(void)
{
    char * key = "123";
    char * message = "Hello, World!";
    char encrypted[20];
    char decrypted[20];

    ResetCipher(key);
    Encrypt(message, encrypted);

    ResetCipher(key);
    Decrypt(decrypted, encrypted);

    printf("output: %s\n", decrypted);

    return 0;
}
1 голос
/ 22 декабря 2008

У меня Blowfish едет без особых проблем. Он утверждает, что быстрее, чем DES.

0 голосов
/ 16 сентября 2017

Вы можете обратиться к приведенному ниже коду для понимания цели. Код использует генератор псевдослучайных чисел для генерации ключа и чисто написан на C.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Function declarations */
int getSize(char *array);
int hashCode(const char *str, int size);
void convertIntToBinaryArray(int num, int *arr, int *index);
void encryptStreamCipher(int key[], int data[], int encypted_data[],int data_size);
void decryptStreamCipher(int key[], int enc_data[], int data_size);
void convertCharToBinary(char c,int *binary_arr,int *index);
void convertStringToBinary(char *str,int *binary_arr, int *size);
void convertBinaryToString(int *data,char *array_string,int *index);
char convertBinaryToChar(char *str);
void displayIntArray(int *array, int size);
void displayCharArray(char *array, int size);
#define MAX_SIZE 10000


int main(int argc, char **argv) {
    char array_string[MAX_SIZE];
    char ascii_key[MAX_SIZE];
    int data[MAX_SIZE];
    int key[MAX_SIZE];
    int encypted_data[MAX_SIZE];
    int seed;
    int key_int;
    int key_size = 0;
    int index;
    int data_size = 0;
    /* 1. Enter the data to encrypt (Do not use space in between)*/
    fprintf(stdout, "Enter data to encrypt: \n");
    fscanf(stdin, "%s", array_string);

    /* 2. Convert the string to binary data */
    convertStringToBinary(array_string,data,&data_size);
    printf("Data in binary: \n");
    displayIntArray(data,data_size);

    /* 3. Read the key string from user */
    fprintf(stdout, "Enter key to encrypt data with: \n");
    fscanf(stdin, "%s", ascii_key);

    /* 4.Get hash code from the key */
    key_size = getSize(ascii_key);
    seed = hashCode(ascii_key, key_size);

    /* 5. Set the key as seed to random number generator to create a key of random bits */
    srand(seed);
    key_int = rand();

    /* 6. Convert key to binary int array */
    convertIntToBinaryArray(key_int, key, &index);
    printf("Key in binary: \n");
    displayIntArray(key,index);

    /* 7. Encrypt : (Binary data) XOR (Binary key) */
    encryptStreamCipher(key, data, encypted_data, data_size);

    /* 8. Display encrypted data */
    printf("encrypted Data: \n");
    displayIntArray(encypted_data,data_size);

    /* 9.Now, Decrypt data and verify initial data */
    decryptStreamCipher(key, encypted_data, data_size);
    printf("Decrypted binary data: \n");
    displayIntArray(encypted_data,data_size);

    /* 10. Convert decrypted data in binary to string */
    memset(array_string,0,sizeof(array_string));
    convertBinaryToString(encypted_data,array_string,&data_size);

    /* 11.Display the original message in string */
    printf("Decrypted Data in String: \n");
    displayCharArray(array_string,data_size);

    return 0;
}

int getSize(char *array) {
    int size = 0;
    int i = 0;
    while ((i != MAX_SIZE) && (array[i] != '\0')) {
        i++;
        size++;
    }
    return size;
}

int hashCode(const char *str, int size) {
    int hash = 0;
    for (int i = 0; i < size; i++) {
        hash = 31 * hash + str[i];
    }
    return hash;
}

void convertIntToBinaryArray(int num, int *arr, int *index) {
    if (num == 0 || *index >= MAX_SIZE)
        return;
    convertIntToBinaryArray(num / 2, arr, index);
    if (num % 2 == 0)
        arr[(*index)++] = 0;
    else
        arr[(*index)++] = 1;

}

void encryptStreamCipher(int key[], int data[], int encypted_data[],
        int data_size) {
    for (int i = 0; i < data_size; i++) {
        encypted_data[i] = data[i] ^ key[i];
    }
}

void decryptStreamCipher(int key[], int enc_data[], int data_size) {
    for (int i = 0; i < data_size; i++) {
        enc_data[i] = enc_data[i] ^ key[i];
    }
}

void convertStringToBinary(char *str,int *binary_arr,int *index) {
    *index=0;
    for (int i = 0; i<strlen(str); i++) {
        convertCharToBinary(str[i],binary_arr,index);
    }
}

void convertCharToBinary(char c,int *binary_arr,int *index) {
    for (int i = 7; i >= 0; --i) {
        binary_arr[*index]=((c & (1 << i)) ? 1 : 0);
        (*index)++;
    }
}

void convertBinaryToString(int *data,char *array_string,int *index){
    int data_size=*index;
    char char_array[data_size];
    *index=0;

    for(int i=0;i<data_size;i++){
        char_array[i]=(data[i] == 1?'1':'0');
    }

    for(int i=0;i<data_size;i=i+8){
        char sub_str[8];
        memcpy(sub_str,char_array+i,8);
        array_string[(*index)++]=convertBinaryToChar(sub_str);
    }
}

char convertBinaryToChar(char *str){
    char c=strtol(str,0,2);
    return c;
}

void displayIntArray(int *array, int size)
{
    for (int i = 0; i < size; i++) {
        printf("%d",array[i]);
    }
    printf("\n");
}

void displayCharArray(char *array, int size)
{
    for (int i = 0; i < size; i++) {
        printf("%c",array[i]);
    }
    printf("\n");
}

Выход:

Введите данные для шифрования: prateekjoshi

Данные в двоичном виде:

01110000011100100110000101110100011001010110010101101011011010100110111101110011011 0100001101001

Введите ключ для шифрования данных с помощью:

пароль

Введите двоичный код:

101010100101110000101101000101

Зашифрованные данные:

11011010001011100100110001100000011001010110010101101011011010100110111101110011011 0100001101001

Расшифрованные двоичные данные:

01110000011100100110000101110100011001010110010101101011011010100110111101110011011 0100001101001

Расшифрованные данные в строке:

prateekjoshi

0 голосов
/ 22 декабря 2008

Вы смотрели на OpenSSL? Он имеет безопасную реализацию множества криптографических алгоритмов и примитивов. Вы не должны использовать это с чем-либо связанным с сетью. Тем не менее, это не очень хорошо документировано или легко учиться. Если вы очень заботитесь о безопасности (например, если вы храните личные данные пользователя, такие как кредитные карты), вам определенно следует использовать OpenSSL или другую безопасную реализацию, а не использовать собственную.

...