Jun
18
使用Linux libc/glibc提供的ecb_crypt来进行DES加密/解密
在"libc 4.6.27 and later, and glibc 2.1 and later"中,提供了 rpc/des_crypt.h这个头文件,其中有几个函数,比如:
这个函数可以用于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会被直接改写。
以下是样例代码:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
void des_setparity(char *key);
int ecb_crypt(char *key, char *data, unsigned datalen, unsigned mode);
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;
}
#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 。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/des_crypt.h>
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);
}
int main(int argc, char *argv[])
{
char Data[4096] = "cea3e8e1659582206e0be32539729e9f";
des_encrypt("12345678", Data, strlen(Data));
printf("the encrypt string is %s;the size is %d\n", Data, strlen(Data));
}
# ./encrypt
the encrypt string is 0;the size is 24