首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于openssl AES解密的派生密钥和iv

用于openssl AES解密的派生密钥和iv
EN

Stack Overflow用户
提问于 2019-03-24 17:28:42
回答 1查看 402关注 0票数 1

我尝试使用C代码中的openssl函数进行AES解密操作,但失败了。

使用openssl命令行工具,我可以成功地解密blob。

代码语言:javascript
复制
openssl enc -d -p -aes-256-cbc -md md5 -in encrypted_file -out clear_file -pass file:./key_file -v

上面的命令运行良好。

但是,当我使用openssl C函数做同样的事情时,它失败了。失败似乎与错误的密钥和从passwd和salt派生的iv有关。

代码语言:javascript
复制
unsigned char key[32];
unsigned char iv[16];
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), salt, key_file_buf, key_size, 1, key, iv);

key_file_buf是从key_file读取的无符号字符缓冲区。

salt和key_file_buf的十六进制转储与命令行中使用的内容相匹配。大小也是正确的(在我的例子中是45字节)。

使用EVP_BytesToKey()返回错误的键和iv会出什么问题?

我尝试过使用iter计数值进行实验,但似乎都没有生成工作密钥和iv。我假设命令行默认的iter计数是1。

同样确认,如果我用命令行显示的工作密钥和iv重写从EVP_BytesToKey()返回的内容和硬编码无符号字符数组,我的代码其余部分就可以正常工作并正确解密。

对于信息,这是其余代码的样子(从不同的来源复制,web上的示例)

代码语言:javascript
复制
EVP_CIPHER_CTX_new();
if(ctx == NULL) {
    printf("Error with EVP_CIPHER_CTX_new.\n");
    return;
}    

if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
    printf("Error initialising decrypted data.\n");
    return;
}    

if(1 != EVP_DecryptUpdate(ctx, clear_data, (int *)&interm_len, &enc_data[salt_size], enc_size)) {
    printf("Error decrypting data.\n");
    return;
}    

*clear_size = interm_len;

if(1 != EVP_DecryptFinal_ex(ctx, clear_data + interm_len, (int *)&interm_len)) {
    printf("Error decrypting data.\n");
    return;
}    
*clear_size += interm_len;

EVP_CIPHER_CTX_free(ctx);

有人能帮帮忙吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-25 08:50:46

终于想明白了!应该是

代码语言:javascript
复制
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), salt, key_file_buf, (key_size-1), 1, key, iv);

如openssl文档中所述

文件:路径名第一行路径名的是密码。如果将相同的路径名参数提供给-passin和-passout参数,则第一行将用于输入密码,下一行将用于输出密码。

我的passwd文件以新行0x0A结束。所以我从EVP_BytesToKey()的buf中删除了它,它返回了正确的密钥& iv,现在可以很好地解密了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55322359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档