在"libc 4.6.27 and later, and glibc 2.1 and later"中,提供了 rpc/des_crypt.h这个头文件,其中有几个函数,比如:
void des_setparity(char *key);
int ecb_crypt(char *key, char *data, unsigned datalen, unsigned mode);

这个函数可以用于DES的加密/解密。详情可以看 man des_crypt ,以下说 ecb_crypt() 函数几个比较坑爹的地方:

1. 虽然提供给DES的密钥(key)是8个字节,但是实际上只用到了其中的56个bit,另外8个bit是用于奇偶校验的(从用户处取得一个64位长的密码key ,去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥)。所以需要调用 des_setparity(key) 来处理key。

2. 必须在data后面补上1~8个 "\x8",以将datalen补齐到8的倍数。对,是1~8个。假设要加密的data是32个字节,需要先补齐到40个字节。

3. 传给des_setparity()的key和给ecb_crypt的data会被直接改写。

以下是样例代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/des_crypt.h>

//注意:这里有个坑,需要保证 data 可以存放的字符串在后面补了\8 不会越界。否则结果是不确定的。
void des_encrypt(const char *key, char *data, int len)
{
    char pkey[8];
    strncpy(pkey, key, 8);
    des_setparity(pkey);
    do {
        data[len++] = '\x8';
    } while (len % 8 != 0);
    ecb_crypt(pkey, data, len, DES_ENCRYPT);
}

void des_decrypt(const char *key, char *data, int len)
{
    char pkey[8];
    strncpy(pkey, key, 8);
    des_setparity(pkey);
    ecb_crypt(pkey, data, len, DES_DECRYPT);
}

int main(int argc, char *argv[])
{
    /*
    * char data[4096] = "cea3e8e1659582206e0be32539729e9f";
    * des_encrypt("12345678", data, strlen(data));
    * printf("%s\n", data);
    * //should be "04fMaWegkH1/BL9CNYxgusFpYK8wdraBX06mPiRmxJP+uVm31GQvyw=="
    */

    char data[4096];
    int i = 0;
    while (EOF != (data[i] = fgetc(stdin))) {
        i++;
    }
    data[i] = '\0';
    des_decrypt("12345678", data, strlen(data));
    printf("%s\n", data);
    /*
    * echo -n 04fMaWegkH1/BL9CNYxgusFpYK8wdraBX06mPiRmxJP+uVm31GQvyw== | base64 -d | ./des
    * should be "cea3e8e1659582206e0be32539729e9f"
    */
    return 0;
}




欢迎扫码关注:




转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php