代码之家  ›  专栏  ›  技术社区  ›  Steven Behnke

C对称流密码

  •  5
  • Steven Behnke  · 技术社区  · 16 年前

    有人能很好地实现用纯可移植C编写的流密码吗?我不太关心此时密码的强度,因为它只是一个概念的证明,但速度是重要的。如果我找不到一个合适的流密码,我想用一个常量来表示。

    7 回复  |  直到 7 年前
        1
  •  6
  •   orip    7 年前

    编辑(2018):使用 NaCl libsodium TweetNaCl 如果您在寻找更小的代码占用空间。它们提供了强大的加密,应该比RC4快得多。

    RC4 是一个非常简单的算法来实现。

    退房 Sterling Camden's implementation Adam Back's implementation .

        2
  •  4
  •   Jason S    16 年前

    ECRYPT eStream 项目。这些是由安全专家判断的严重的核心密码算法。据我所知,所有的候选算法都需要包括纯C(非C++)中的一个实现。

    编辑:这个网站的优点在于它深入了解了不同的算法,包括它们已知的弱点,并包括 performance benchmarks 也。

        3
  •  2
  •   Brian Knoblauch    16 年前

    对于纯POC应用程序,您可以快速将ROT13投入使用。 http://en.wikipedia.org/wiki/ROT13

    然而,我在提出建议时非常犹豫,因为太频繁的简单的POC代码,以后就要被替换,永远不会……

        4
  •  1
  •   David Norman    16 年前

    我得到了 Blowfish 没有太多麻烦。它声称比DES更快。

        5
  •  1
  •   James Eichele Bernard Igiri    16 年前

    这里是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;
    }
    
        6
  •  0
  •   Jay Conrod    16 年前

    你看过openssl吗?它有许多加密算法和原语的安全实现。你不必在任何网络相关的地方使用它。然而,它并没有很好的文档记录,也不容易学习。如果您非常关心安全性(例如,如果您存储的是诸如信用卡之类的私人用户数据),那么您肯定应该使用OpenSSL或其他安全实现,而不是滚动自己的实现。

        7
  •  0
  •   Prateek Joshi    8 年前

    为了理解目的,您可以参考下面的代码。该代码使用伪随机数生成器生成密钥,并纯用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");
    }
    

    输出:

    输入要加密的数据: 普拉契科乔希

    二进制数据:

    011100011100100110000101110010101100101011010110101101101101101101110011011 0100001101001

    输入用于加密数据的密钥:

    密码

    二进制关键字:

    1010100101110001101000101

    加密数据:

    11011010001011100100110001100000010010101100101011010111011010011011110110011011 0100001101001

    解密的二进制数据:

    011100011100100110000101110010101100101011010110101101101101101101110011011 0100001101001

    字符串中的解密数据:

    普拉契科乔希