为何mbedtls的AES加密结果与Java及在线工具不一致?
问题排查与修复:AES CBC加密结果不一致
核心问题分析
你的代码和Java/在线工具结果不一致,主要是填充方式不匹配,另外还有两处潜在问题需要修正:
明文填充方式错误
AES CBC要求明文长度必须是16字节(AES-128块大小)的整数倍。你用memset把剩余字节填0,属于零填充;但Java和在线工具默认使用PKCS#7填充:需要填充N个字节时,每个填充字节的值就是N。比如"hello"长度为5,需要填充11个0x0b字节,而非0x00。IV被加密函数修改
mbedtls_aes_crypt_cbc会直接修改传入的IV数组,后续如果复用IV会导致错误,建议传入IV的副本。输入输出缓冲区重叠
同时用input作为明文输入和密文输出,存在内存操作风险,应分开使用独立缓冲区。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "mbedtls/aes.h" #include "mbedtls/base64.h" int main() { unsigned char key[] = "6c74ea86f5c867f1"; unsigned char iv_original[] = "5e64fe04bfd8363b"; // 复制IV避免被函数修改 unsigned char iv[16]; memcpy(iv, iv_original, 16); unsigned char plaintext[16] = {0}; const char* input_str = "hello"; size_t input_len = strlen(input_str); memcpy(plaintext, input_str, input_len); // 应用PKCS#7填充 size_t pad_len = 16 - (input_len % 16); memset(plaintext + input_len, pad_len, pad_len); mbedtls_aes_context aes; mbedtls_aes_init(&aes); mbedtls_aes_setkey_enc(&aes, key, 128); // 使用独立的密文缓冲区 unsigned char ciphertext[16] = {0}; mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, plaintext, ciphertext); // 打印密文十六进制(可选) int i; for (i=0; i<16; i++) { printf("%02x ", ciphertext[i]); } printf("\n"); size_t outlen = 0; char *dst = (char *)malloc(200); if (dst == NULL) { printf("malloc failed\n"); return 1; } // Base64编码密文(长度16字节) mbedtls_aes_base64_encode(dst, 200, &outlen, ciphertext, 16); printf("cipher is: %s \n", dst); // 清理资源 mbedtls_aes_free(&aes); free(dst); return 0; }
验证结果
修复后执行代码,得到的Base64结果会和Java/在线工具一致:Fr00ZupbEBVr4gwL/l+G2w==
内容的提问来源于stack exchange,提问作者fad99daf
相关产品推荐
相关产品推荐

