2012-03-28 44 views
1

我正在使用OpenSSL lib,並且使用AES加密/解密獲得了非常奇怪的效果:如果我將更改加密消息中的某個字節並解密它,我會看到原始消息的一部分,假設是。這是源代碼: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);  
} 

什麼可能是錯誤的?

回答

6

問題是你的期望是整個消息因爲單個字節被改變而變得不可讀。

消息的哪些部分變得不可讀取取決於所選的加密模式。你正在使用CFB。這意味着如果更改密文中的單個字節,則相應的字節和之後的塊將被損壞,密碼會從錯誤中恢復。

PCBC將在錯誤發生後破壞所有輸出。但它仍然沒有檢測到錯誤。

我建議添加身份驗證(MAC或具有集成身份驗證的模式,如AES-GCM)。

+0

Park Cities Baptist Church? – 2012-03-28 19:45:27

+0

啊,從來沒有見過這種模式在使用:) – 2012-03-28 20:16:04

+0

@owlstead我也沒有。它聽起來也不是很有用。一旦添加了認證,錯誤行爲就不再重要了。 – CodesInChaos 2012-03-28 20:17:49

2

這正是應該的。

大大簡化了,消息從左向右進行了加密和解密。在解密例程命中改變的字節之前,解密的文本必須與原始消息匹配。更改後的字節會發生什麼情況取決於密碼模式,但左側部分的解密不會受到此更改的影響。