【问题标题】:openssl md5 in command line and php md5 produce different results命令行中的 openssl md5 和 php md5 产生不同的结果
【发布时间】:2017-05-16 01:46:18
【问题描述】:

这是我使用命令行作为文本文件 (csr.txt) 提交的字符串 https://pastebin.com/qBLJcKQB

我传递的openssl命令是:

openssl req -noout -modulus -in csr.txt | openssl md5

e199562f2e9f6a29826745d09faec3a6

这里是获取 md5 哈希的 php 脚本版本

<?php 

$csr = '-----BEGIN CERTIFICATE REQUEST-----
MIIBxzCCATACAQAwgYYxCzAJBgNVBAYTAlVLMQ8wDQYDVQQIDAZMb25kb24xDTAL
BgNVBAcMBEJsYWgxDjAMBgNVBAoMBUJsYWgxMQ4wDAYDVQQLDAVCbGFoMjETMBEG
A1UEAwwKSm9lIEJsb2dnczEiMCAGCSqGSIb3DQEJARYTb3BlbnNzbEBleGFtcGxl
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsfzWjyj7zlVFlXCaGMH6
Gj3jsWV2tC6rLnRKK4x7hUaI0JriqXUQTNYKTgVhDslR1K0zrJYcaqpmwb4PrUJ/
2RY5si7QvHnndwJ3NOdHFOK8ggn1QqRvFFo4ssPpYWGY63Abj0Df9O6igEHQRQtn
5/9WkkM8evLLmS2ZYf9v6W8CAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBADLYvFDq
IfxN81ZkcAIuRJY/aKZRcxSsGWwnuu9yvlAisFSp7xN3IhipnPwU2nfCf71iTe/l
SZifofNpqrnamKP90X/t/mjAgXbg4822Nda1HhbPOMx3zsO1hBieOmTQ9u03OkIZ
hkuQmljK8609PGUGcX5KeGBupZPVWJRf9ly7
-----END CERTIFICATE REQUEST-----';

$csrDetails = openssl_pkey_get_details(openssl_csr_get_public_key($csr)); 

echo md5($csrDetails['rsa']['n']);
?> 

php 脚本产生:

718926bb97aabc0fd1116fa25c295612

我已经看到其他讨论排除新行的线程,但在我的情况下,我没有使用 echo,而是使用 openssl。 Why PHP's md5 is different from OpenSSL's md5?

感谢一些帮助。

注意:如果我从命令行“| openssl md5”& 在 php 脚本中删除 md5() 则结果相同

php 脚本产生:

echo strtoupper(bin2hex($csrDetails['rsa']['n']));

B1FCD68F28FBCE554595709A18C1FA1A3DE3B16576B42EAB2E744A2B8C7B854688D09AE2A975104CD60A4E05610EC951D4AD33AC961C6AAA66C1BE0FAD427FD91639B22ED0BC79E777027734E74714E2BC8209F542A46F145A38B2C3E9616198EB701B8F40DFF4EEA28041D0450B67E7FF5692433C7AF2CB992D9961FF6FE96F

【问题讨论】:

  • “但在我的情况下,我没有使用 echo,而是使用 openssl。” - 没关系。如果该文本文件的末尾包含一个空行,则它确实包含一个(不可见的)换行符\n。您可以尝试修剪它或去掉空行。
  • 我添加了这段代码来修剪 php 脚本中的新行,但对结果没有影响: $csr = str_replace("\r\n", "\n", $csr );
  • 试试str_replace("\r\n", "", $csr) 或str_replace("\n", "", $csr) - 你现在正在寻找\r\n 并将其替换为\n。同时运行 var_dump
  • 这样做会破坏 php 脚本,因为 php 的内置 openssl 库需要新行来读取字符串。
  • 看起来 openssl 在“openssl req ...”命令的输出末尾添加了一个“\n”。从 php 尝试运行 md5("Modulus=B1FCD68F28...\n"),即注意使用 " 而不是 ' 和最后的 \n。我试过了,得到了 "e199562f2e9f6a29826745d09faec3a6" - 与 OpenSSL 命令行相同

标签: php openssl md5


【解决方案1】:

在 php 版本中,您正在散列模数的二进制表示,即二进制数据 0xB1FCD68F28.... 在命令行版本中,您正在散列模数的可打印文本字符串表示,即字符串“Modulus=B1FCD68F28 ……”。假设您在使用基于 ASCII 字符集的机器上,这将转换为二进制数据 0x4D6F64756C...因此,您在每种情况下都在散列不同的数据,因此您将得到不同的结果。

此外,openssl 似乎在“openssl req ...”命令的输出末尾添加了一个“\n”。从 php 尝试运行 md5("Modulus=B1FCD68F28...\n"),即注意使用 " 而不是 ' 和最后的 \n。我尝试过并得到 "e199562f2e9f6a29826745d09faec3a6" - 与 OpenSSL 命令行相同

【讨论】:

  • 为了使 php 与命令行版本匹配,我最终这样做了:echo "Modulus=".strtoupper(bin2hex($csrDetails['rsa']['n']))."\n";
猜你喜欢
  • 2014-05-28
  • 2011-03-11
  • 2017-06-12
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多