我正在使用此命令来签署文件:
openssl dgst -binary -sha1 -out signedFile.bin -sign file.pem plainText
我想知道这个命令的输出格式是什么。我的目的是解析结果并提取哈希数组。
格式是什么?有没有什么工具可以解析结果?
答案1
如果file.pem 包含一个 RSA 私钥(在这种情况下,该名称具有误导性),输出是一个“裸” RSAPKCS#1(v1.5)签名——一个 N 位数,其中 N 是模数大小,必要时向上舍入,但这种情况很少发生,因为人们通常使用 1024 和 2048 这样的密钥大小,而没有任何通常用于签名的元数据。dgst -sign
默认值为,-binary
因此是多余的(仅哈希形式dgst
不存在),但正如@zedman9991 所说,你可以要求-hex
。
但解析这个是没有意义的。它是一个数字。如果你想“恢复”签名的哈希值,PKCS#1 支持它,但其他 RSA 格式可能不支持,其他算法如 DSA 和 ECDSA 肯定不支持,你需要 (1) 进行 modexp-e 计算(通常不准确地称为“用公钥解密”),然后 (2) 取消填充,然后 (3) ASN.1 解码。“解析”可能合理地表示 (2) 或 (3) 或两者。你可以编写一个 C 程序来完成这些操作,大概 20 行。给定二进制文件,rsautl -verify
执行 (1) 和 (2)(给定 v1.5 填充,这是dgst -sign
默认值),你可以手动或使用执行 (3) asn1parse
:
c:\work>echo test >in & od -tx1 in
0000000 74 65 73 74 20 20 0d 0a
0000010
c:\work>openssl dgst -sha1 -hex in
SHA1(in)= a02bfe060e0d7857137b7082124541237ed740c7
c:\work>openssl dgst -sha1 -sign rsakey.pem in >sig & od -tx1 sig
0000000 53 e3 68 70 69 d9 fd 1f b1 83 6e eb 1c 6f 58 ab
0000020 b5 44 88 3f d2 67 19 21 9b 95 39 bb ce 2d 7c ac
0000040 51 03 c3 a5 61 7e 47 f6 4b e1 c0 4a 74 ee 7f 29
0000060 b2 cc ff 91 20 97 c4 f9 2e 3e 9f 61 06 62 e3 fe
0000100 ea 4c 3f a6 3b da b4 03 62 81 a7 8c 91 b7 d5 49
0000120 8c d1 e9 92 ff 4b 97 c0 b5 74 59 4d 19 e1 57 c9
0000140 a8 98 f4 c8 df 70 b4 89 57 b0 24 f5 b0 a9 69 b4
0000160 dd ed a0 26 73 bd ca ad a0 f9 e2 0e ea fe 39 8d
c:\work>openssl rsautl -verify -inkey rsakey.pem <sig >rec & od -tx1 rec
Loading 'screen' into random state - done
0000000 30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 a0
0000020 2b fe 06 0e 0d 78 57 13 7b 70 82 12 45 41 23 7e
0000040 d7 40 c7
0000043
c:\work>openssl asn1parse -inform der <rec
0:d=0 hl=2 l= 33 cons: SEQUENCE
2:d=1 hl=2 l= 9 cons: SEQUENCE
4:d=2 hl=2 l= 5 prim: OBJECT :sha1
11:d=2 hl=2 l= 0 prim: NULL
13:d=1 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:A02BFE060E0D7857137B7082124541237ED740C7
“恢复”的签名 DER 的最后一个字段(OCTET STRING)的值(在这种情况下也是其最后 20 个八位字节)是哈希值。
(为了举一个简单的例子,我使用了 1024 位 RSA 密钥,因此使用了 128 字节的签名。现在认为 RSA-1024 在可预见的未来存在被破解的风险,因此安全应用程序通常需要至少 1536,通常需要 2048 或更高。)