2014-12-30 26 views
1

我有一些使用openssl(AES_*)函數進行加密的數據。我想更新此代碼以使用較新的(EVP_*)函數。但應該能夠解密使用舊代碼加密的數據。使用AES_ *函數和EVP_ *函數進行加密

我粘貼了舊代碼和新代碼。加密/解密的內容是不同的。即我不能交替使用它們。這意味着我無法升級代碼而無需使用舊代碼進行解密,然後重新加密。

是否有任何參數值爲EVP_BytesToKey,這樣aes_key派生在兩種情況下都是相同的。或者有沒有其他方法可以使用(EVP_*)函數來實現?我嘗試了幾個不同的值digest,rounds,並嘗試製作iv NULL,但並沒有真正起作用,即它沒有提供與舊方法相同的輸出。

使用AES_*功能

#include <stdio.h> 
#include <openssl/aes.h> 
#include <print_util.h> 

static const unsigned char user_key[] = { 
    0x00, 0x01, 0x02, 0x03, 
    0x10, 0x11, 0x12, 0x13, 
    0x20, 0x21, 0x22, 0x23, 
    0x30, 0x31, 0x32, 0x33 
}; 

int main() 
{ 
    unsigned char p_text[]="plain text"; 
    unsigned char c_text[16]; 
    unsigned char d_text[16]; 

    AES_KEY aes_key; 

    AES_set_encrypt_key(user_key, 128, &aes_key); 
    AES_encrypt(p_text, c_text, &aes_key); 

    printf("plain text = %s\n", p_text); 
    printbuf((char*)c_text, 16, "cipher text = "); 

    AES_set_decrypt_key(user_key, 128, &aes_key); 
    AES_decrypt(c_text, d_text, &aes_key); 
    printf("plain text (decrypted) = %s \n", d_text); 

    return 0; 
} 

使用EVP_*函數的代碼的代碼。 (加密代碼如下,解密代碼相似)。

#include <strings.h> 
#include <openssl/evp.h> 
#include <print_util.h> 

static const unsigned char user_key[16] = { 
    0x00, 0x01, 0x02, 0x03, 
    0x10, 0x11, 0x12, 0x13, 
    0x20, 0x21, 0x22, 0x23, 
    0x30, 0x31, 0x32, 0x33 
}; 

int main() 
{ 
    EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); 
    EVP_CIPHER_CTX_init(ctx); 

    const EVP_CIPHER *cipher = EVP_aes_128_ecb(); // key size 128, mode ecb 
    const EVP_MD *digest = EVP_md5(); 
    int rounds = 10; 
    unsigned char aes_key[EVP_MAX_KEY_LENGTH]; 
    unsigned char aes_iv[EVP_MAX_IV_LENGTH]; 

    EVP_BytesToKey(cipher, digest, NULL, user_key, 16, rounds, aes_key, aes_iv); 

    EVP_EncryptInit(ctx, cipher, aes_key, aes_iv); 

    unsigned char p_text[]="plain text"; int p_len = sizeof(p_text); 
    unsigned char c_text[16]; int c_len = 16; 
    int t_len; 

    EVP_EncryptUpdate(ctx, c_text, &c_len, p_text, p_len); 
    EVP_EncryptFinal(ctx, (c_text + c_len), &t_len); 

    c_len += t_len; 

    printf("==> p_text: %s\n", p_text); 
    printbuf((char*)c_text, c_len, "==> c_text:"); 
} 

感謝

+0

第一個示例使用原始密鑰,而第二個示例使用密鑰派生函數('EVP_BytesToKey')。 ECB模式不使用初始化向量。 AES加密始終在16字節塊(AES塊大小)上運行,因此您在字符串「純文本」後加密垃圾郵件,因爲該字符串只有10個字節。 'EVP_Encypt'在調用'Final'時添加PKCS填充。 – jww

+0

你應該*不*使用'AES_encrypt'和朋友。您應該使用'EVP_ *'功能。如果可用,'EVP_ *'功能使用硬件,如AES-NI。請參閱OpenSSL wiki上的[EVP Symmetric Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption)。事實上,您應該使用經過身份驗證的加密,因爲它提供了*機密性和真實性。請參閱OpenSSL wiki上的[EVP Authenticated Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption)。 – jww

+0

[OpenSSL 1.1.0c更改了摘要算法](http://stackoverflow.com/q/39637388/608639)在某些內部組件中使用。以前使用MD5,1.1.0切換到SHA256。請注意,這些更改不會影響'EVP_BytesToKey'和像'openssl enc'這樣的命令。 – jww

回答

2

你不必在你的代碼AES_*任何密鑰推導,所以如果你想留下來完全兼容,你不應該使用任何密鑰推導如EVP_BytesToKey在新EVP_代碼。

不,沒有辦法使EVP_BytesToKey輸出與上面相同的密鑰,因爲使用加密哈希來生成輸出。

+0

我試着避免使用'EVP_BytesToKey',並直接使用'user_key'來使用NULL'iv',但這也不起作用。 –

+1

我會建議引入向後兼容性代碼,並過渡人們使用新功能 – nrathaus