[英]why aes encryption result from mbedtls is different than java and online tool result?
我有以下尝试使用 AES CBC 加密密码加密“hello”的 C 代码片段。 但有些情况下,来自以下代码 (mbedtls) 的加密结果与 Java 代码结果和在线工具结果不同。 我是 ac 编程语言的新手,我试着四处搜索,但无法弄清楚问题出在哪里。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbedtls/aes.h"
#include "mbedtls/base64.h"
#include "mbedtls/md5.h"
#include "mbedtls/cipher.h"
int main()
{
unsigned char key[] = "6c74ea86f5c867f1";
unsigned char iv[] = "5e64fe04bfd8363b";
unsigned char input[100] = {0};
memset(input, 0, 100 );
strcpy(input, "hello");
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc( &aes, key, 128 );
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, input, input );
int i;
for (i=0; i<100; i++)
{
printf("%x ",input[i]);
}
printf("\n");
size_t outlen=0;
char *dst = (char *)malloc(sizeof(char)*200);
mbedtls_base64_encode(dst, 100, &outlen, input, 16);
printf("cipher is: %s \n", dst);
}
上面的代码打印“密码是:W9T3jTvbtfYGUZ3yXkQ6wA==”,但是使用相同密钥和 iv 的 java 加密结果是“Fr00ZupbEBVr4gwL/l+G2w==”,来自https://www.devglan.com/的结果也是如此 在线工具/aes-加密-解密
有人可以帮我吗?
您的代码看起来几乎是正确的,我认为问题可能在于:
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, input, input );
因为您的输入缓冲区与输出缓冲区相同。
尝试使用两种不同的缓冲区(一种用于输入,一种用于输出)。
然后看看是否能解决问题。
mbedtls_aes_crypt_cbc
的文档没有提及重叠input
和output
缓冲区。
编辑:
我想我找到了罪魁祸首。
这也是我自己过去遇到的问题。
当输入不是 16 字节对齐时,有多种方法可以“填充”输入。
在您的代码中,您用零填充缓冲区 0 但有一些方法可以用 0 以外的其他内容填充输入。
可能 mbedtls 具有一项功能,可让您将输入填充到现有标准(网站 devglan.com 使用的标准)。
引用来自不同 stackexchange 站点的另一个答案:
有多种填充数据的方法,可以完全破坏给定加密程序与其他程序的兼容性。 对称密码和操作模式中最常用的填充方法当然是PKCS#7 。
(强调我的)
因此,您可能需要为输入数据填充“PKCS#7”。
而且,一个问题的评论员说了关于直接使用mbedtls_aes_ mbedtls_aes_*
函数:
我应该补充一点,您很可能不应该使用 mbedtls_aes_xxx 函数。 它们主要用作更高级别 API 的构建块,而不是供应用程序直接使用。 在应用程序代码中硬编码加密算法是个坏主意:如果您在代码中输入字母 AES,那您就错了。
这是有道理的,与mbedtls_cipher_*
函数一样,您可以指定如何填充输入数据(顺便说一句, mbedtls_cipher_set_padding_mode
默认为 PKCS#7)。
底线:
我认为您应该尝试使用mbedtls_cipher_*
函数来解决您的问题,而不是使用mbedtls_aes_*
* 来解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.