Question Comment calculer la valeur RSA-SHA1 (sha1WithRSAEncryption) avec OpenSSL


Je suis confus à propos de RSA-SHA1, je pensais que c'était RSA_private_encrypt (SHA1 (message)). Mais je ne peux pas obtenir la valeur de signature correcte. Y a-t-il quelque chose qui ne va pas?


12
2018-06-12 01:46


origine


Réponses:


Oui, le cryptage PKCS # 1 et les signatures PKCS # 1 sont différent. Dans le cas du cryptage (celui que vous avez essayé), le message d'entrée est simplement rempli avant d'être exponentié.

Les signatures PKCS # 1, d’autre part, calculeront d’abord une structure ASN.1 DER du formulaire.

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

Ceci est ensuite rempli à nouveau pour former le message encodé EM

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

où PS est une chaîne de remplissage de 0xff de longueur suffisante. Si vous reproduisez cette EM et utilisez RSA_private_encrypt, vous obtiendrez alors l'encodage de signature PKCS # 1 v1.5 correct, le même que vous obtiendriez avec RSA_sign ou même mieux, en utilisant le générique EVP_PKEY_sign.

Voici une petite démonstration en 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

Le hachage SHA-256 imprime comme suit:

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

dec_signed est le résultat de RSA_sign déchiffré à nouveau avec la clé publique - cela nous redonne exactement l'entrée à la fonction RSA avec le remplissage supprimé et, en l'occurrence, c'est exactement la DigestInfo structure mentionnée ci-dessus:

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

Comme vous pouvez le voir, la valeur de la digest domaine de DigestInfo est le même que le hash SHA-256 que nous avons calculé nous-mêmes.


8
2018-06-12 14:43



Je pense que vous travaillez au mauvais niveau d'abstraction OpenSSL; vous devriez probablement utiliser le rsa.hfonction déclarée RSA_sign() et RSA_verify(), qui devaient être utilisés sur PKCS # 1signatures conformes.


3
2018-06-12 02:03