我想通过套接字发送使用RSA加密的大数据。我使用openssl
和c
。
由于RSA解密速度很慢,我首先使用通用和直接的方式使用AES加密数据,然后使用RSA加密使用的AES密码。然后我通过套接字发送AES加密数据和RSA加密密码,并以相反的方式进行加密。
我使用以下方式进行AES加密:
EVP_CIPHER_CTX en;
unsigned char password[65];
int i, x = 0;
unsigned char key[32], iv[32];
unsigned char *ciphertext;
i = dataLength + AES_BLOCK_SIZE -1;
ciphertext = (unsigned char *)malloc(i);
EVP_CIPHER_CTX_init(&en);
EVP_EncryptInit_ex(&en, EVP_aes_256_cbc(), NULL, key, iv);
EVP_EncryptUpdate(&en, ciphertext, &i, (unsigned char*)data, dataLength);
EVP_EncryptFinal_ex(&en, ciphertext+i, &x);
但如何安全地创建key
和iv
?现在我使用以下功能:
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, 64, 9, key, iv);
我的问题是: 如何正确创建“密码”?
因为如果我使用rand()
或类似的东西,我的尝试完全没用,因为任何能够落后于用于“密码”生成的“随机性”的人都能够解密数据而无需关心RSA加密“密码”。
openssl
是否有安全密码生成功能?或者EVP_BytesToKey()
只是错误的方式来做我想做的事情?
答案 0 :(得分:3)
幸运的是,默认的RAND_bytes
方法是每个线程播种的,默认情况下使用操作系统提供的随机数生成器。 OpenSSL文档似乎已经过时涉及Windows,但您可以通过查看the answer of the venerable Thomas Pornin on security.stackoverflow.com找到更多相关信息。
EVP_BytesToKey
用于从密码生成密钥。 EVP_BytesToKey
是特定于OpenSSL的密钥派生函数(KDF)。 OpenSSL还实现了PBKDF2,这是NIST批准的基于密码的密钥派生函数(PBKDF)的方法。但是,由于您需要随机密钥而不是派生密钥,因此这些功能都不适用。
所以请使用rand()
。如果可能,请尝试检查特定平台的播种功能。
另请注意某些内部组件中使用的OpenSSL 1.1.0c changed the digest algorithm。以前使用MD5,1.1.0切换到SHA256。请注意,更改不会影响EVP_BytesToKey
和openssl enc
等命令。