贴一下反编译出来的源码
int v22; int v42;
unsigned int v29;
char *v19; char *v30;
_BYTE v38[3];
1
lcdtyph 2020-03-17 20:59:32 +08:00
因为加密完 text 存储的已经不是字符串了啊,没有\0 做结尾了。所以 digestString 很有可能读到不属于 text 的值。你要用的是
md5.digestMemory((char *)text, sizeof text); |
2
dtsdao OP @lcdtyph text 数组我自认为已经开的挺大了,之前开小了连 windows 结果都不正确
说实话,我觉得用 C++写这个真的头疼,这段是反编译出来的所以看着特别难受,用其它语言改写总是结果不对 |
3
lcdtyph 2020-03-17 21:24:42 +08:00
@dtsdao #2 结果都不正确原因是 digestString 不知道读到哪里才停止啊,如果你加密之后的数据里没有'\0'或者'\0'在中间就出现了你的 md5 结果肯定不对啊,这和你 text 数组开多大有什么关系呢?
|
4
BrettD 2020-03-17 21:29:05 +08:00 via iPhone
是不是逻辑写错了
|
5
dtsdao OP @lcdtyph 我试了一下用 digestMemory,运行结果还是不一样。
Line 27: puts(md5.digestMemory(text, sizeof text)); input:test1234 Linux:a54e0cfdb3158654122d193cdf29c6e5 Windows:fb4c2c022c39db620d88476666f5f79a |
6
dtsdao OP @BrettD 逻辑不是我写的,是反编译的。Windows 跑得很好,Linux 就不行了。源程序是用的 NDK 生成的 arm 的 so,我手里没有源码。
|
7
sfqtsh 2020-03-17 21:44:19 +08:00 via Android
1 换行符\r\n
2 getchar 的返回类型是 int |
10
dtsdao OP |
11
springz 2020-03-17 22:35:34 +08:00
问问题好歹给一个最小可复现,再说反编译,额。总是想到不好的事情。
|
13
lcdtyph 2020-03-17 22:50:51 +08:00 1
@dtsdao #12
我吐了,md5.h 里面有一行 typedef unsigned long int UINT4; 这导致 UINT4 在 64 位 unix 机器上根本不是 4byte,而是 8byte。而 win 上 long 总是 4byte 的所以 win 上的结果是对的。 |
14
lcdtyph 2020-03-17 23:01:38 +08:00
你可以把那行改成
#include <stdint.h> typedef uint32_t UINT4; |
15
dtsdao OP @lcdtyph 草,我就猜是这样,我还以为是 uint_8 的事呢,结果查了半天 tinyaes 相关问题都没查出来,感谢您帮忙定位,这个库太坑了。顺便求下用其他库改写的源码,这个真的看着太丑了。
问题相关: https://stackoverflow.com/questions/697361/md5-hash-calculates-differently-on-server |
17
dtsdao OP 话说写这个玩意的人貌似根本就没管 AES 的 Padding 之类的吧,我觉得它能运行都很神奇,要不是登录校验需要的话打死不会用 C 复现的...
|
18
lcdtyph 2020-03-18 00:07:35 +08:00
@dtsdao #15
``` #include <stdio.h> #include <mbedtls/md.h> #include <mbedtls/cipher.h> uint8_t text[80] = {'t', 'e', 's', 't', '1', '2', '3', '4'}; int main() { uint8_t buf[16] = {0}; mbedtls_md_context_t md5; mbedtls_md_init_ctx(&md5, mbedtls_md_info_from_type(MBEDTLS_MD_MD5)); mbedtls_md_starts(&md5); mbedtls_md_update(&md5, text, sizeof text); mbedtls_md_finish(&md5, buf); for (int i = 0; i < sizeof buf; ++i) { printf("%02hhx", buf[i]); } printf("\n"); return 0; } ``` |
19
dtsdao OP @lcdtyph 我说的倒不是 MD5,主要是前面那块 AES,直接用 AES_ECB_encrypt 就对,加了 padding 就错,如果能用 openssl 改写就好了
|
20
lcdtyph 2020-03-18 00:49:19 +08:00
@dtsdao #19
ECB 模式无所谓 padding,因为他默认输入是 16byte 的整数倍,就是要求自己 padding。在你的代码里其实就相当于 zero padding ``` #include <stdio.h> #include <stdint.h> #include <string.h> #include <mbedtls/md.h> #include <mbedtls/cipher.h> uint8_t key[] = "88a2a91ee2126bfd"; uint8_t text[80] = {'t', 'e', 's', 't', '1', '2', '3', '4'}; uint8_t len = 0; int main() { mbedtls_cipher_context_t ctx; mbedtls_cipher_init(&ctx); mbedtls_cipher_setup(&ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB)); mbedtls_cipher_setkey(&ctx, key, 128, MBEDTLS_ENCRYPT); mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_ZEROS); uint8_t buf[80]; size_t olen = sizeof buf; size_t idx = 0; mbedtls_cipher_update(&ctx, text, 16, buf + idx, &olen); idx += olen; olen = (sizeof buf) - idx; mbedtls_cipher_finish(&ctx, buf + idx, &olen); idx += olen; mbedtls_cipher_free(&ctx); for (int i = 0; i < idx; ++i) { printf("%02hhx", buf[i]); } printf("\n"); return 0; } ``` ECB 模式其实也不需要上面的 mbedtls_cipher_finish,但是为了过程完整我还是写出来了 |