如何使用OpenSSL计算RSA-SHA1(sha1WithRSAEncryption)值 [英] How to compute RSA-SHA1(sha1WithRSAEncryption) value with OpenSSL

查看:3699
本文介绍了如何使用OpenSSL计算RSA-SHA1(sha1WithRSAEncryption)值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对RSA-SHA1感到困惑,我认为它是RSA_private_encrypt(SHA1(message))。
但是我无法获得正确的签名值。是的,PKCS#1加密和PKCS#1签名是

ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf\">不同的



另一方面,PKCS#1签名将首先计算一个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函数,删除padding,结果是,这是 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 /...\">]

如您所见,摘要 DigestInfo 的字段与我们自己计算的SHA-256哈希相同。


I'm confused about RSA-SHA1, I thought it's RSA_private_encrypt(SHA1(message)). But I can't get the correct signature value. Is there anything wrong?

解决方案

Yes, PKCS#1 encryption and PKCS#1 signatures are different. In the encryption case (the one you tried), the input message is simply padded before it is exponentiated.

PKCS#1 signagtures on the other hand will first calculate an ASN.1 DER structure of the form

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

This is then padded again to form the encoded message EM

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

where PS is a padding string of 0xff of sufficient length. If you reproduce this EM and use RSA_private_encrypt, then you will get the correct PKCS#1 v1.5 signature encoding, the same you would get with RSA_sign or even better, using the generic EVP_PKEY_sign.

Here's a little demonstration in 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

The SHA-256 hash prints out as follows:

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

dec_signed is the result of RSA_sign decrypted again with the public key - this gives us back exactly the input to the RSA function with the padding removed, and as it turns out, this is exactly the DigestInfo structure mentioned above:

 #<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/...">]>

As you can see, the value of the digest field of DigestInfo is the same as the SHA-256 hash that we computed ourselves.

这篇关于如何使用OpenSSL计算RSA-SHA1(sha1WithRSAEncryption)值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆