2014-01-21 69 views
1

我想通過套接字發送用RSA加密的大數據。我使用opensslc如何爲RSA/AES加密生成密碼

由於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); 

但我怎麼創建keyiv安全?現在,我使用下面的功能:

EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, 64, 9, key, iv); 

我的問題是: 如何創建「密碼」是否正確?

因爲如果我使用rand()或其他相同的東西,我的嘗試是完全無用的,因爲任何能夠獲得用於「密碼」生成的「隨機性」的人都能夠解密數據,而無需關心RSA加密密碼」。

openssl中有安全密碼生成功能嗎?或者是EVP_BytesToKey()只是錯誤的方式來做我想做的事情?

+0

看看集成加密系統是如何工作的。 Shoup的[ECIES](http://www.shoup.net/papers/iso-2_1.pdf);或Abdalla,Bellare和Rogaway的[DHIES](http://charlotte.ucsd.edu/~mihir/papers/dhaes.pdf)。更好的是,使用該系統而不是重新發明它。這些方案生成所有參數,用分組密碼進行加密,添加完整性標籤,然後使用公鑰加密包裝對稱密鑰。 ECIES系統包裝在橢圓曲線中,而DHIES使用Diffie-Hellman問題。 – jww

回答

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_BytesToKeyopenssl enc之類的命令。

+0

我將「AESKey」更改爲「密碼」,因爲這有點令人誤解。我是否正確理解了我應該使用'rand()'生成隨機字符密碼並使用此密碼生成密鑰,並使用'EVP_BytesToKey'生成iv? – Genius

+0

絕對不是。您的AES密鑰應該只包含使用rand()生成的隨機字節。似乎沒有必要輸入密碼或字符。如果你每次使用一個隨機的AES密鑰,你可以使用一個由零組成的靜態IV,否則它應該像密鑰一樣由隨機字節組成。 –

+2

另請注意,AES密碼不存在。AES是分組密碼,現代分組密碼需要密鑰,而不是密碼。這個二進制密鑰應該與隨機無法區分。密碼不是隨機的二進制數據 - 您需要某種轉換(PBKDF)將密碼轉換爲密鑰。即便如此,從密碼生成的密鑰通常比完全隨機的AES密鑰弱得多。 –