keytool 和 openssl 证书指纹不匹配
Mismatch in keytool and openssl certificate fingerprint
我试图在 META-INF/ 中对 android 开发者证书进行指纹识别,以供研究之用。
我发现在某些情况下,keytool 和 openssl 的输出会给我相同证书的不同 SHA1 指纹:
使用密钥工具:
keytool -princert -file META-INF/CERT.RSA
...
SHA1: 9D:17:FB:AB:67:BB:D0:7B:12:FE:E8:33:7D:66:F1:C4:2B:03:BD:F7
...
使用 openssl:
openssl pkcs7 -inform DER -in META-INF/CERT.RSA -print_certs -out CERT.cert
openssl x509 -in CERT.cert -fingerprint -noout
SHA1 Fingerprint=80:D5:CD:66:6E:44:75:62:A8:B3:7E:5D:AC:00:DE:1D:FF:6B:E6:CA
这是否正常 - keytool 使用其自己的方式对证书进行指纹识别,这与 openssl- 不同,是我做错了什么,还是某处存在错误?
顺便说一句,我不是专家,所以请随时提出任何建议,即使是最基本的建议!
如果您需要这方面的示例,我可以为您提供发生这种情况的 android 应用程序的名称。
提前致谢。
不同的SHA1指纹是由代码签名证书的不同编码引起的。
第一个指纹(通过 keytool)是根据证书字节计算的,与 PKCS#7 文件中包含的完全一样 META-INF/CERT.RSA
。签名(证书的,而不是代码的签名)的长度在这里以两个字节编码,实际上一个字节就足够了。要看到这一点,我们必须查看 CERT.RSA
的 ASN.1 转储。有几个程序可以做到这一点,但我推荐 Peter Gutmann 的 dumpasn1/GUIdumpASN。相关部分是这样的:
<06 09>
532 9: OBJECT IDENTIFIER
: sha1WithRSAEncryption (1 2 840 113549 1 1 5)
<05 00>
543 0: NULL
: }
<03 82 00 81>
545 129: BIT STRING
: 65 26 30 0C 41 32 63 75 e&0.A2cu
: 2F B7 DF 9A 96 37 72 1B /....7r.
字节82 00 81
是在long form中编码的BITSTRING(证书的签名)的长度字节。
根据 Distinguished Encoding Rules DER,“必须使用最短的可能长度编码”,本来应该是 81 81
。这意味着代码签名证书不是完全 DER 编码的。
当您使用 openssl 导出证书时,它将证书重新编码为有效的 DER:
<03 81 81>
489 129: BIT STRING
: 65 26 30 0C 41 32 63 75 e&0.A2cu
: 2F B7 DF 9A 96 37 72 1B /....7r.
因此证书的哈希值(指纹)不同,已经改变了。
keytool 和 openssl 都没有做错。 DER 编码的要点在于它始终生成与 ASN.1 结构完全相同的字节表示形式。
导致此问题的软件是用于创建错误代码签名证书的工具。
我试图在 META-INF/ 中对 android 开发者证书进行指纹识别,以供研究之用。
我发现在某些情况下,keytool 和 openssl 的输出会给我相同证书的不同 SHA1 指纹:
使用密钥工具:
keytool -princert -file META-INF/CERT.RSA
...
SHA1: 9D:17:FB:AB:67:BB:D0:7B:12:FE:E8:33:7D:66:F1:C4:2B:03:BD:F7
...
使用 openssl:
openssl pkcs7 -inform DER -in META-INF/CERT.RSA -print_certs -out CERT.cert
openssl x509 -in CERT.cert -fingerprint -noout
SHA1 Fingerprint=80:D5:CD:66:6E:44:75:62:A8:B3:7E:5D:AC:00:DE:1D:FF:6B:E6:CA
这是否正常 - keytool 使用其自己的方式对证书进行指纹识别,这与 openssl- 不同,是我做错了什么,还是某处存在错误?
顺便说一句,我不是专家,所以请随时提出任何建议,即使是最基本的建议!
如果您需要这方面的示例,我可以为您提供发生这种情况的 android 应用程序的名称。
提前致谢。
不同的SHA1指纹是由代码签名证书的不同编码引起的。
第一个指纹(通过 keytool)是根据证书字节计算的,与 PKCS#7 文件中包含的完全一样 META-INF/CERT.RSA
。签名(证书的,而不是代码的签名)的长度在这里以两个字节编码,实际上一个字节就足够了。要看到这一点,我们必须查看 CERT.RSA
的 ASN.1 转储。有几个程序可以做到这一点,但我推荐 Peter Gutmann 的 dumpasn1/GUIdumpASN。相关部分是这样的:
<06 09>
532 9: OBJECT IDENTIFIER
: sha1WithRSAEncryption (1 2 840 113549 1 1 5)
<05 00>
543 0: NULL
: }
<03 82 00 81>
545 129: BIT STRING
: 65 26 30 0C 41 32 63 75 e&0.A2cu
: 2F B7 DF 9A 96 37 72 1B /....7r.
字节82 00 81
是在long form中编码的BITSTRING(证书的签名)的长度字节。
根据 Distinguished Encoding Rules DER,“必须使用最短的可能长度编码”,本来应该是 81 81
。这意味着代码签名证书不是完全 DER 编码的。
当您使用 openssl 导出证书时,它将证书重新编码为有效的 DER:
<03 81 81>
489 129: BIT STRING
: 65 26 30 0C 41 32 63 75 e&0.A2cu
: 2F B7 DF 9A 96 37 72 1B /....7r.
因此证书的哈希值(指纹)不同,已经改变了。
keytool 和 openssl 都没有做错。 DER 编码的要点在于它始终生成与 ASN.1 结构完全相同的字节表示形式。
导致此问题的软件是用于创建错误代码签名证书的工具。