【问题标题】:OpenSSL and AESOpenSSL 和 AES
【发布时间】:2012-03-28 14:35:02
【问题描述】:

我正在使用 OpenSSL 库并通过 AES 加密/解密获得非常奇怪的效果:如果我将更改加密消息中的一些字节并对其进行解密,我将看到原始消息的一部分,这是不应该的是。这是源代码:

#include <openssl/evp.h> 
#include <string.h>

int do_crypt(void) 
{  
 int outlen, inlen;  
 FILE *in, *out;  
 in = fopen("in.txt", "r"); 
 out = fopen("out.txt", "w"); 
 unsigned char key[32];
 strcpy(key, "10000000000000000000000000000002"); 
 unsigned char iv[8];
 unsigned char inbuf[BUFSIZE], outbuf[BUFSIZE];  
 EVP_CIPHER_CTX ctx;  
 const EVP_CIPHER * cipher;    


 EVP_CIPHER_CTX_init(&ctx);   
 cipher = EVP_aes_256_cfb(); 
 EVP_EncryptInit(&ctx, cipher, key, 0); 

while(1) {                    
 inlen = fread(inbuf, 1, BUFSIZE, in);  
 if(inlen <= 0) break;  
 if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) return 0;  
 fwrite(outbuf, 1, outlen, out);  
 }    

if(!EVP_EncryptFinal(&ctx, outbuf, &outlen)) return 0;  
 fwrite(outbuf, 1, outlen, out);  
 EVP_CIPHER_CTX_cleanup(&ctx);  
 return 1;  
} 

int do_decrypt(char *infile) 
{  
 int outlen, inlen;  
 FILE *in, *out;  
 in = fopen("out.txt", "r"); 
 out = fopen("out2.txt", "w"); 
 unsigned char key[32];
 strcpy(key, "10000000000000000000000000000002"); 
 unsigned char iv[8];  
 unsigned char inbuf[BUFSIZE], outbuf[BUFSIZE];  
 EVP_CIPHER_CTX ctx;  

 EVP_CIPHER_CTX_init(&ctx);  
 EVP_DecryptInit(&ctx, EVP_aes_256_cfb(), key, 0);  

 while(1) {  
 inlen = fread(inbuf, 1, BUFSIZE, in);  
 if(inlen <= 0) break;  
 if(!EVP_DecryptUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) return 0; 
 fwrite(outbuf, 1, outlen, out);  
 }  

 if(!EVP_DecryptFinal(&ctx, outbuf, &outlen)) return 0;  
 fwrite(outbuf, 1, outlen, out);  
 EVP_CIPHER_CTX_cleanup(&ctx);  
 return 1;  
} 

main(int argc, char **argv){ 
if(atoi(argv[1]) == 1) 
    do_crypt(0); 
if(atoi(argv[1]) == 2) 
    do_decrypt(0);    
} 

可能出了什么问题?

【问题讨论】:

    标签: c linux cryptography openssl aes


    【解决方案1】:

    问题是您期望整个消息变得不可读,因为单个字节已更改。

    消息的哪些部分变得不可读取决于所选的加密模式。您正在使用 CFB。这意味着如果您更改密文中的单个字节,则相应的字节和之后的块会损坏,然后密码会从错误中恢复。

    PCBC 将在出错后损坏所有输出。但它仍然没有检测到错误。

    我建议添加身份验证(MAC 或具有集成身份验证的模式,例如 AES-GCM)。

    【讨论】:

    • 啊,没见过那个模式在用:)
    • @owlstead 我也没有。听起来也不是很有用。添加身份验证后,错误行为就不再重要了。
    【解决方案2】:

    这正是应该的。

    大大简化,消息从左到右加密和解密。在解密例程命中更改的字节之前,解密的文本必须与原始消息匹配。更改字节后发生的情况取决于密码模式,但文本左侧部分的解密不受此更改的影响。

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 2020-09-26
      • 2011-07-30
      相关资源
      最近更新 更多