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
中發生。填充應該包含所需的字節數以獲得正確的塊大小,用每個字節填充該數字。但它似乎充滿了隨機數據(或可能更多的加密?)
是否有這個代碼的問題,這可以解釋爲什麼加密是不正確的? 我應該關注不正確的填充以及如何在這種情況下進行調試嗎?
任何指針?