从OpenSSL 1.0.2b迁移至3.x后AES-128-ECB解密填充异常
OpenSSL 3.x AES-ECB 加密解密后明文残留填充数据问题
我有一个测试程序,链接OpenSSL 1.0.2b时运行正常,但切换到OpenSSL 3.0.0和3.3.0后出现异常。问题出在加密端:解密过程无报错返回,但明文仍残留填充数据,具体表现为:
- 输入长度为块大小整数倍时,明文末尾多出一块16字节的0x10填充块,未被剥离;
- 输入长度非块大小整数倍时,明文倒数第二块会被原末尾字节填充至整块,再追加一块0x10填充块,导致明文超出预期长度。
我尝试过显式启用/禁用填充、预获取密码上下文,但都没有效果。禁用填充时,虽无末尾0x10块,但非整块输入仍会残留填充。密钥为16字节(128位),输入输出缓冲区大小足够。
加密代码
// Encrypt data_length bytes of data into enc_data using key EVP_CIPHER_CTX* ctx{EVP_CIPHER_CTX_new()}; if ( !ctx ) { return -1; } EVP_CIPHER* cipher{EVP_CIPHER_fetch(nullptr, "AES-128-ECB", nullptr)}; if ( !cipher ) { return -1; } // Explicitly enable padding - doesn't seem to matter int padding{1}; OSSL_PARAM params[2]; params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_PADDING,&padding); params[0] = OSSL_PARAM_construct_end(); if ( EVP_EncryptInit_ex2(ctx,cipher,key,nullptr,params) != 1 ) { return -1; } int input_ptr{0}; int output_ptr{0}; // Encrypt until the output_ptr meets or exceeds the input data_length while ( output_ptr < data_length ) { int this_enc_len{0}; if ( EVP_EncryptUpdate(ctx,reinterpret_cast<unsigned char*>(enc_data) + output_ptr,&this_enc_len,reinterpret_cast<unsigned char*>(data) + input_ptr, data_length - input_ptr) != 1 ) { return -1; } input_ptr += this_enc_len; output_ptr += this_enc_len; } int final_enc_len{0}; if ( EVP_EncryptFinal_ex(ctx,reinterpret_cast<unsigned char*>(enc_data) + output_ptr,&final_enc_len) != 1 ) { return -1; } output_ptr += final_enc_len; // Cleanup omitted for brevity return output_ptr;
解密代码
// Decrypt data_length bytes of data into dec_data using key EVP_CIPHER_CTX* ctx{EVP_CIPHER_CTX_new()}; if ( !ctx ) { return -1; } EVP_CIPHER* cipher{EVP_CIPHER_fetch(nullptr, "AES-128-ECB", nullptr)}; if ( !cipher ) { return -1; } // Explicitly enable padding - doesn't seem to matter here either int padding{1}; OSSL_PARAM params[2]; params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_PADDING,&padding); params[0] = OSSL_PARAM_construct_end(); if ( EVP_DecryptInit_ex2(ctx,cipher,key,nullptr,params) != 1 ) { return -1; } int input_ptr{0}; int output_ptr{0}; while ( output_ptr < data_length ) { int this_enc_len{0}; if ( EVP_DecryptUpdate(ctx,reinterpret_cast<unsigned char*>(dec_data) + output_ptr,&this_enc_len,reinterpret_cast<unsigned char*>(data) + input_ptr, data_length - input_ptr) != 1 ) { return -1; } input_ptr += this_enc_len; output_ptr += this_enc_len; } int final_enc_len{0}; if ( EVP_DecryptFinal_ex(ctx,reinterpret_cast<unsigned char*>(dec_data) + output_ptr,&final_enc_len) != 1 ) { return -1; } output_ptr += final_enc_len; // Cleanup again omitted for brevity return output_ptr;
有没有人遇到过类似问题?求解决方案或变通方法。
内容的提问来源于stack exchange,提问作者rutgersmike
相关产品推荐
相关产品推荐

