为什么PHP的md5和OpenSSL的md5不同?

8

我有些困惑,不明白为什么在PHP和OpenSSL中进行MD5哈希得到的结果不同。

下面是我运行的代码:

php -r "echo md5('abc');"

结果为:900150983cd24fb0d6963f7d28e17f72

而这个:

echo abc | openssl md5

结果为:0bee89b07a248e27c83fc3d5951213c1

为什么呢?


说句实话,犯这个错误的人很多。例如,在 Stack Overflow 上已经有好几次提出了这个问题:
  • https://dev59.com/BkjSa4cB1Zd3GeqPFn3P
  • http://stackoverflow.com/questions/1604892/is-the-md5sum-linux-command-working-right
  • https://dev59.com/ZUrSa4cB1Zd3GeqPYKQB
  • https://dev59.com/sE3Sa4cB1Zd3GeqPxK_C
- Bill Karwin
那让我感觉好些了 :) 谢谢 :) - Alex N.
4个回答

22

只有一种方法可以计算MD5。

一个猜想是第二个字符串在被哈希处理时也包含了一个换行符。

没错,已经验证。就是这样。


5
很奇怪,但是 echo 会返回一个新行符。使用 echo -n abc | openssl md5 可以得到与 PHP 版本相同的输出结果。 - artlung

8

众所周知,问题在于echo会输出一个额外的换行符。

然而,提出的解决方案(echo -n)并不完全正确。根据POSIX标准,“实现不应支持任何选项。”如果您不使用它,您将使世界变得更好。使用

printf %s abc | openssl md5

或者简单地说
printf abc | openssl md5

1
POSIX标准还规定:如果第一个操作数是-n,或者任何操作数包含反斜杠( '\')字符,则结果是实现定义的。(在同一页下方) - 这是XSI扩展规定的,-n必须被处理为普通字符串(如果系统符合XSI,则可以使用echo“abc\c”代替)。 - caf

6

echo 命令通常在输出字符串末尾添加一个换行符,这就是为什么 MD5 值会不同的原因。

尝试使用 echo -n abc | openssl md5 命令。


1
如jdehaan所指出的,如果你告诉echo不输出换行符,你将得到你期望的答案。
echo -n "abc" | openssl md5
900150983cd24fb0d6963f7d28e17f72

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接