2015-04-01 137 views
0

我需要加密一個URL。根據URL的規格,它應該是(Rijndael)使用CBC加密模式進行編碼,使用0的IV,PKCS7填充和128位的密鑰長度。比較AES加密OpenSSL與.NET(RijndaelManaged)

URL的解密是在使用RijndaelManaged類的.NET環境中完成的。我加密使用OpenSSL 1.0.2a(C++非託管),並使用下面的代碼(來自互聯網):

// ctx holds the state of the encryption algorithm so that it doesn't 
// reset back to its initial state while encrypting more than 1 block. 
EVP_CIPHER_CTX ctx; 
EVP_CIPHER_CTX_init(&ctx); 

unsigned char key[] = {0x41, 0x41, 0x45, 0x43, 0x41, 0x77, 0x51, 0x46, 
            0x43, 0x67, 0x63, 0x49, 0x43, 0x5A, 0x6F, 0x4C }; 
unsigned char iv[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
assert(sizeof(key) == 16); // AES128 key size 
assert(sizeof(iv) == 16); // IV is always the AES block size 

// If data isn't a multiple of 16, the default behavior is to pad with 
// n bytes of value n, where n is the number of padding bytes required 
// to make data a multiple of the block size. This is PKCS7 padding. 
// The output then will be a multiple of the block size. 
std::string plain("someId=007&accountNo=119955244351&user=admin&"); 
std::vector<unsigned char> encrypted; 
size_t max_output_len = plain.length() + 16 - (plain.length() % 16); 
encrypted.resize(max_output_len); 

// Enc is 1 to encrypt, 0 to decrypt, or -1 (see documentation). 
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 

// EVP_CipherUpdate can encrypt all your data at once, or you can do 
// small chunks at a time. 
int actual_size = 0; 
if(!EVP_CipherUpdate(&ctx, 
       &encrypted[0], &actual_size, 
       reinterpret_cast<unsigned char *>(&plain[0]), plain.size())) 
{ 
    EVP_CIPHER_CTX_cleanup(&ctx); 
} 

// EVP_CipherFinal_ex is what applies the padding. If your data is 
// a multiple of the block size, you'll get an extra AES block filled 
// with nothing but padding. 
int final_size; 
EVP_CipherFinal_ex(&ctx, &encrypted[actual_size], &final_size); 
actual_size += final_size; 

encrypted.resize(actual_size); 

for(size_t index = 0; index < encrypted.size(); ++index) 
{ 
    std::cout << std::hex << std::setw(2) << std::setfill('0') << 
        static_cast<unsigned int>(encrypted[index]); 
} 
std::cout << "\n"; 

EVP_CIPHER_CTX_cleanup(&ctx); 

AESWrapper aesWrapper; 
std::string encryptedbase64(aesWrapper.base64encode(&encrypted[0], encrypted.size())); 

我檢查(顯然)鍵,IV和算法AES-CBC-128 afaik OpenSSL默認使用PKCS7填充,但結果不匹配!

引人注意的是填充似乎不會在EVP_CipherFinal_ex中發生。填充應該包含所需的字節數以獲得正確的塊大小,用每個字節填充該數字。但它似乎充滿了隨機數據(或可能更多的加密?)

是否有這個代碼的問題,這可以解釋爲什麼加密是不正確的? 我應該關注不正確的填充以及如何在這種情況下進行調試嗎?

任何指針?

回答

0

沒關係。我得到了它的工作。解密URL的C#應用​​程序在密鑰上使用SHA1哈希。在加密它開始工作的URL之前,我對密鑰進行了哈希處理。