【问题标题】:Manually created signature in certificate signing request is not matching with the openssl req generated signature证书签名请求中手动创建的签名与 openssl req 生成的签名不匹配
【发布时间】:2021-01-02 13:07:42
【问题描述】:
  • 使用以下命令创建证书签名请求:
$ openssl genrsa -out test.key 2048
$ openssl req -new -key test.key -subj "/CN=foo" -out foo.csr
  • 借助@marc 提供的步骤,我从中提取了 4 个文件:

    • info.der (openssl asn1parse -in foo.csr -strparse 4 -out info.der)
    • pub.pem (openssl req -pubkey -in foo.csr -noout -out pub.pem)
    • hash.manual(保存的命令"sha256 info.der"的十六进制输出)
    • sig.raw (openssl asn1parse -in foo.csr -strparse 338 -out sig.raw)
  • 我的理解/怀疑是,foo.csr 中提到的“签名”只不过是带有私钥“test.key”的“hash.manual”的“加密输出”。所以为了验证我的理解,我使用了

$ openssl rsautl -encrypt -in hash_manual -inkey test.key -out manual_signature
  • 现在,当我对这两个文件执行 diff 时,它们不匹配,并且 hexdump -C 确认 sig.raw 与 (openssl req -in csr --text) 中提到的签名输出匹配。

  • 请帮助澄清为什么 manual_signature 和 sig.raw 不匹配。

【问题讨论】:

  • verify 的倒数是sign,而不是encrypt
  • sign/signatue == rsa_encruption of (hash of (data)) ??这是我的理解。如果不是,请纠正我。
  • 是的,但它使用私钥加密(请参阅rsautl man page)。普通加密使用公钥加密。因为其他算法不是这样工作的,所以我们通常说signverify。因为test.key 包含私钥和公钥,所以openssl 只使用它需要的那个。

标签: encryption openssl public-key-encryption


【解决方案1】:

你有两个问题:

  • 您需要使用sign 而不是encrypt。对于 RSA,encrypt 是使用公钥加密,而sign 是使用私钥加密
  • rsautl 的输出格式错误

第一个很容易修复,只需使用-sign

第二个有点烦人,不仅仅是sha256输出被签名,它是一个ASN.1结构,看起来像这样:

    0:d=0  hl=2 l=  49 cons: SEQUENCE          
    2:d=1  hl=2 l=  13 cons:  SEQUENCE          
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL              
   17:d=1  hl=2 l=  32 prim:  OCTET STRING      
      0000 - dc 31 c9 99 51 ce 03 a2-aa 14 13 f1 c4 f6 3e ea   .1..Q.........>.
      0010 - 4f 87 a2 56 37 de 7f a7-c1 87 49 f0 43 c9 ba bb   O..V7.....I.C...

最后的 OCTET STRING 字段是原始的 sha256 哈希。

最简单的生成方法是使用openssl dgst 结合散列和签名:

# Hash and sign the certificationRequestInfo
$ openssl dgst -sha256 -sign test.key info.der > manual_signature

# Compare to extracted sig.raw (no output means no diff)
$ diff manual_signature  sig.raw

# Verify both the extracted sig.raw and the manual_signature using the public key
$ openssl rsautl -verify -pubin -inkey pub.pem -in sig.raw -asn1parse
    0:d=0  hl=2 l=  49 cons: SEQUENCE          
    2:d=1  hl=2 l=  13 cons:  SEQUENCE          
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL              
   17:d=1  hl=2 l=  32 prim:  OCTET STRING      
      0000 - dc 31 c9 99 51 ce 03 a2-aa 14 13 f1 c4 f6 3e ea   .1..Q.........>.
      0010 - 4f 87 a2 56 37 de 7f a7-c1 87 49 f0 43 c9 ba bb   O..V7.....I.C...

$ openssl rsautl -verify -pubin -inkey pub.pem -in manual_signature -asn1parse
    0:d=0  hl=2 l=  49 cons: SEQUENCE          
    2:d=1  hl=2 l=  13 cons:  SEQUENCE          
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL              
   17:d=1  hl=2 l=  32 prim:  OCTET STRING      
      0000 - dc 31 c9 99 51 ce 03 a2-aa 14 13 f1 c4 f6 3e ea   .1..Q.........>.
      0010 - 4f 87 a2 56 37 de 7f a7-c1 87 49 f0 43 c9 ba bb   O..V7.....I.C...

【讨论】:

  • 谢谢@Marc。了解使用 openssl dgst 一步完成哈希和签名的便利性。
  • 当我使用私钥使用 openssl rsautl echo boo > boo openssl rsautl -encrypt -in boo -inkey test.key -out boo.encrypted.withprivatekey openssl rsautl -encrypt -in boo -pubin -inkey pub.pem -out boo.encrypted.withpublickey diff boo.encrypted.withprivatekey boo.encrypted.withpublickey - Binary files boo.encrypted.withprivatekey and boo.encrypted.withpublickey differ 使用私钥加密文件时出现奇怪行为输入然后不确定为什么 boo.encrypted.withprivatekeyboo.encrypted.withpublickey 不同?
  • 这是意料之中的,RSA 加密使用随机填充(rsautl 的默认值为PKCS#1 v1.5)以确保任何接近安全的地方。请注意,如果您多次运行相同的加密命令,您最终也会得到不同的结果。详情见this cryptography.se问题。
猜你喜欢
  • 2021-03-11
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多