【发布时间】:2015-02-27 02:33:36
【问题描述】:
我有一些使用 openssl (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:");
}
谢谢
【问题讨论】:
-
您的第一个示例使用原始密钥,而您的第二个示例使用密钥派生函数 (
EVP_BytesToKey)。 ECB 模式不使用初始化向量。 AES 加密始终在 16 字节块(AES 块大小)上运行,因此您在字符串"plain text"之后加密垃圾,因为该字符串只有 10 个字节。EVP_Encypt在调用Final时添加 PKCS 填充。 -
你应该不使用
AES_encrypt和朋友。您应该使用EVP_*函数。EVP_*函数使用硬件,如 AES-NI(如果可用)。请参阅 OpenSSL wiki 上的 EVP Symmetric Encryption and Decryption。事实上,您可能应该使用经过身份验证的加密,因为它提供 机密性和真实性。请参阅 OpenSSL wiki 上的 EVP Authenticated Encryption and Decryption。 -
OpenSSL 1.1.0c changed the digest algorithm 用于一些内部组件。以前使用MD5,1.1.0改用SHA256。请注意,
EVP_BytesToKey和openssl enc等命令中的更改不会影响您。
标签: encryption cryptography openssl aes evp-cipher