【发布时间】:2014-10-01 15:54:34
【问题描述】:
我使用openssl 生成了一个公钥/私钥对:
openssl genrsa -out private.pem 1024
openssl pkcs8 -topk8 -in private.pem -outform DER -out private.der -nocrypt
openssl rsa -in private.pem -pubout -outform DER -out public.der
之后,我使用 Python 创建了测试代码,用于加密和解密字符串。我直接从PyCrypto 文档中拿了这个例子,加密:
string_to_encrypt = str(raw_input("Enter a string to encrypt: "))
print "Encrypting: %s" % string_to_encrypt
key = RSA.importKey(open('./public.der').read())
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(string_to_encrypt)
和解密:
dec_key = RSA.importKey(open('./private.der').read())
d_cipher = PKCS1_OAEP.new(dec_key)
dec_message = d_cipher.decrypt(ciphertext)
现在这可以按预期工作,接下来我想尝试使用C 破译相同的内容。我通过socket 将数据传输到C 应用程序.. 但现在我无法将消息恢复为明文,即使解密不会引发错误。
在我尝试破译文本之前,我将数据打印到屏幕上,并且两端的字节匹配。接收函数如下所示:
char* decrypt_packet(char* encrypted_buffer, int size) {
FILE *keyfile = fopen("./private.pem", "r");
RSA *rsa_pri = PEM_read_RSAPrivateKey (keyfile, NULL, NULL, NULL);
int rsa_private_len = RSA_size(rsa_pri);
for(i; i < size;i++)
printf("%02x:",(unsigned char)encrypted_buffer[i]);
printf("\n");
char * decrypt = (char*)malloc(rsa_private_len+1);
memset(decrypt,0,rsa_private_len+1); //Zero the buffer for printing
int res = RSA_private_decrypt(rsa_private_len, (unsigned char*)encrypted_buffer, (unsigned char*)decrypt, rsa_pri , RSA_NO_PADDING);
if(res == -1) {
ERR_load_crypto_strings();
printf("ERROR: %s\n",ERR_error_string(ERR_get_error(),NULL));
}
printf("size decrypt: %i\n", res);
printf("decrypted: %s\n", decrypt);
....
解密没有失败,但输出是垃圾(这里只发送一个测试字符串“hello world”):
received buffer:
82:9d:a7:f7:3c:d6:71:12:01:31:ba:c6:a2:90:94:90:fd:69:d3:fe:14:11:2f:af:a9:8a:25:99:55:d2:84:1f:dc:e3:5e:a9:be:7b:8a:ac:cd:38:76:a2:91:ec:24:da:06:c7:8d:67:c8:15:19:73:c8:57:ce:a5:87:f0:da:db:c2:6d:5b:55:a3:ba:7e:7d:ca:6b:02:23:fd:fe:cb:b4:04:53:e2:74:c3:91:77:ee:5f:7a:61:7a:87:a6:42:37:28:c6:9c:cb:6a:46:f4:c0:bd:fe:8a:92:da:86:53:3b:5c:e2:e3:79:81:2c:32:28:9c:4c:be:0a:fa:75:7b:b2:
size decrypt: 128
decrypted: dÕf`5åiõuy<òáµÛ~G=/
Ä
我选择使用RSA_NO_PADDING?我真的不知道这是否正确。
但如果我使用其他东西,解密函数会报错:RSA_padding_check_PKCS1_type_2:block type is not 02 或 RSA_padding_check_PKCS1_OAEP:oaep decoding error
我是否正确调用了RSA_private_decrypt 函数?问题可能是我正在阅读 C 中的 private.pem 文件(在 Python 中我正在阅读 .der 文件)?
又想到了一件事。我使用来自 Ubuntu 的默认 openssl 来生成密钥,但我的 C 应用程序链接到下载和编译的源代码。 Makefile 包含:
SOURCE_FILES = main.c client_handler.c
CC=gcc
$(CC) $(SOURCE_FILES) -o client_control_srv -lpthread -lssl -lcrypto -I/home/jlumme/openssl-1.0.1f_x86/include
感谢您的任何提示!
【问题讨论】:
-
你肯定需要使用padding;撇开您在加密上进行了填充,因此您必须在解密时进行填充这一事实不谈,如果没有正确填充,RSA 是非常不安全的。
-
不使用填充时没有错误并不令人惊讶;与大多数密码一样,RSA 没有经过身份验证,因此不知道某些内容是否正确解密。 128 字节的输出基本上只是填充的 blob(1024 位)。不知道为什么当您使用 PKCS1_OAEP 解密时它会失败;除非缓冲区在某处损坏,否则 应该 工作。顺便说一句,为什么这被标记为“aes”?
-
@CBHacking,感谢您的评论。我 99% 确定传输的字节是我加密的(在两端我一个接一个地打印它们,我只是在问题中跳过它们以保持简单).. 不管我如何把它转过来 RSA_private_decrypt 不会如果我有 RSA_PKCS1_PADDING 或 RSA_PKCS1_OAEP_PADDING,则不会返回成功。我什至尝试过 RSA_SSLV23_PADDING,但问题仍然存在:/
标签: c encryption aes rsa public-key-encryption