Подтвердить что ты не робот

Как вычислить значение RSA-SHA1 (sha1WithRSAEncryption) с помощью OpenSSL

Я смущен RSA-SHA1, я думал, что это RSA_private_encrypt (SHA1 (сообщение)). Но я не могу получить правильную подпись. Что-то не так?

4b9b3361

Ответ 1

Да, шифрование PKCS # 1 и сигнатуры PKCS # 1 разные. В случае шифрования (тот, который вы пробовали) входное сообщение просто дополняется до того, как оно будет экспоненциальным.

PKCS # 1 signagtures, с другой стороны, сначала вычислит структуру DER ASN.1 формы

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, который мы вычислили сами.

Ответ 2

Я думаю, что вы работаете с неправильным уровнем абстракции OpenSSL; вероятно, вы должны использовать функцию rsa.h -declared RSA_sign() и RSA_verify(), которые должны были использоваться на PKCS # 1 - совместимые подписи.