命令行中的 openssl md5 和 php md5 产生不同的结果

openssl md5 in command line and php md5 produce different results

这是我用命令行提交的文本文件 (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

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

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