如何计算与OpenSSL的RSA-SHA1(sha1WithRSAEncryption)值(How

2019-06-25 09:51发布

我感到困惑的RSA-SHA1,我认为这是RSA_private_encrypt(SHA1(消息))。 但我不能得到正确的签名值。 有什么不对的吗?

Answer 1:

是的,PKCS#1加密和PKCS#1签名不同 。 在加密情况下(一个你试过),它是幂之前只是被填充的输入消息。

PKCS#另一方面1 signagtures将首先计算如下形式的ASN.1 DER结构

DigestInfo ::= SEQUENCE {
    digestAlgorithm AlgorithmIdentifier,
    digest OCTET STRING
}

这然后再次填充以形成编码消息EM

EM = 0x00 || 0x01 || PS || 0x00 || T

其中PS是足够长的0xff的的填充串。 如果您重现此EM和使用RSA_private_encrypt ,那么你会得到正确的PKCS#1 v1.5的签名编码,你会用得到相同RSA_sign甚至更好,使用通用EVP_PKEY_sign 。

下面是Ruby的一个小演示:

require 'openssl'
require 'pp'

data = "test"
digest = OpenSSL::Digest::SHA256.new
hash = digest.digest("test")
key = OpenSSL::PKey::RSA.generate 512

signed = key.sign(digest, data)
dec_signed = key.public_decrypt(signed)

p hash
pp OpenSSL::ASN1.decode dec_signed

的SHA-256散列打印出来,如下所示:

"\x9F\x86\xD0\x81\x88L}e\x9A/..."

dec_signed的结果是RSA_sign用公钥解密再次-这使我们回到完全输入到RSA功能与填充去除,事实证明,这正是DigestInfo上述结构:

 #<OpenSSL::ASN1::Sequence:0x007f60dc36b250
 @infinite_length=false,
 @tag=16,
 @tag_class=:UNIVERSAL,
 @tagging=nil,
 @value=
  [#<OpenSSL::ASN1::Sequence:0x007f60dc36b318
    @infinite_length=false,
    @tag=16,
    @tag_class=:UNIVERSAL,
    @tagging=nil,
    @value=
     [#<OpenSSL::ASN1::ObjectId:0x007f60dc36b390
       @infinite_length=false,
       @tag=6,
       @tag_class=:UNIVERSAL,
       @tagging=nil,
       @value="SHA256">,
      #<OpenSSL::ASN1::Null:0x007f60dc36b340
       @infinite_length=false,
       @tag=5,
       @tag_class=:UNIVERSAL,
       @tagging=nil,
       @value=nil>]>,
   #<OpenSSL::ASN1::OctetString:0x007f60dc36b2a0
    @infinite_length=false,
    @tag=4,
    @tag_class=:UNIVERSAL,
    @tagging=nil,
    @value="\x9F\x86\xD0\x81\x88L}e\x9A/...">]>

正如你所看到的,价值digest领域DigestInfo是一样的SHA-256散列,我们计算出自己。



Answer 2:

我认为你在错误的OpenSSL的抽象层次工作; 你或许应该使用的rsa.h -declared功能RSA_sign()RSA_verify()它的目的是要对要使用的PKCS#1兼容的签名。



文章来源: How to compute RSA-SHA1(sha1WithRSAEncryption) value with OpenSSL