2015-08-28 181 views
0

我需要加密我的數據,所以我使用AES加密它們。我可以加密短數據。但我需要加密長數據,它不能工作。我可以怎樣解決這個問題。這是我的代碼。如何使用AES(openssl)加密數據?

#include "cooloi_aes.h" 
CooloiAES::CooloiAES() 
    : MSG_LEN(0) 
{ 
    for(int i = 0; i < AES_BLOCK_SIZE; i++) 
    { 
    key[i] = 32 + i; 
    } 
} 

CooloiAES::~CooloiAES() 
{ 

} 

std::string CooloiAES::aes_encrypt(std::string msg) 
{ 
    int i = msg.size()/1024; 
    MSG_LEN = (i + 1) * 1024; 

char in[MSG_LEN]; 
char out[MSG_LEN]; 
memset((char*)in,0,MSG_LEN); 
memset((char*)out,0,MSG_LEN); 

strncpy((char*)in,msg.c_str(),msg.size()); 

unsigned char iv[AES_BLOCK_SIZE]; 
for(int j = 0; j < AES_BLOCK_SIZE; ++j) 
{ 
    iv[j] = 0; 
} 

AES_KEY aes; 
if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0) 
{ 
    return NULL; 
} 
int len = msg.size(); 

AES_cbc_encrypt((unsigned char*)in,(unsigned char*)out,len,&aes,iv,AES_ENCRYPT); 

std::string encrypt_msg(&out[0],&out[MSG_LEN+16]); 
std::cout << std::endl; 
return encrypt_msg; 
} 

std::string CooloiAES::aes_decrypt(std::string msg) 
{ 
    MSG_LEN = msg.size(); 

    char in[MSG_LEN]; 
char out[MSG_LEN+16]; 
memset((char*)in,0,MSG_LEN); 
memset((char*)out,0,MSG_LEN+16); 

strncpy((char*)in,msg.c_str(),msg.size()); 

std::cout << std::endl; 

unsigned char iv[AES_BLOCK_SIZE]; 
for(int j = 0; j < AES_BLOCK_SIZE; ++j) 
{ 
    iv[j] = 0; 
} 

AES_KEY aes; 
if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0) 
{ 
    return NULL; 
} 
int len = msg.size(); 
AES_cbc_encrypt((unsigned char*)in,(unsigned char*)out,len,&aes,iv,AES_DECRYPT); 
std::string decrypt_msg = out; 
return decrypt_msg; 
} 

當我加密具有96字節的數據,它將failed.I得到這個錯誤 「終止叫做拋出 '的std :: length_error' 的實例以後有什麼():basic_string的:: _ S_create 」。但我不認爲這個字符串比最大長度長,而且我也不會出錯。

+0

我加密了96個字節的數據,然後我解密它,我弄亂了代碼,所以我說它不能工作。 – Nicholas

+0

其實,我沒有分割我的字節,我第一次使用這種模式,所以我不知道該怎麼做。 – Nicholas

+0

這對你有幫助嗎? http://stackoverflow.com/questions/5132939/how-to-do-aes-decryption-using-openssl?rq=1 – Madness

回答

0

你有什麼錯在你的加密/解密除了填充問題以及處理二進制打交道時strncpy()函數和(的char *)構造函數的用法。如果數據不適合全部16個字節,則不應加密最後一個數據塊。所以,你應該實現自己的填充或不過去的小塊可言,你的代碼將被簡化爲這個加密:

string aes_encrypt/decrypt(string msg) 
{ 
     unsigned char out[msg.size()]; 
     memcpy((char*)out,msg.data(),msg.size()); 
     AES_cbc_encrypt((unsigned char *)msg.data(),out,msg.size()/16*16,&aes,iv,AES_ENCRYPT **or** AES_DECRYPT); 
     return string((char *)out, msg.size()); 
} 

總結:

  • 不使用函數strncpy()與二進制
  • 不使用string s = binary_char_massive;構造
  • 沒有數據的最後部分進行加密,如果它不適合與塊大小或墊它自己
  • 使用EVP_ * OpenSSL的API是否有PO未來算法變化的可能性
+0

謝謝,但我仍然有一個問題,純文本的大小有限制? – Nicholas

+0

是的,字符串:: max_size() –

+0

我加密一個字符串的所有「一」有103字節,但我的地穴,我只得到87字節,所以我想知道哪裏錯了。 – Nicholas