2011-04-14 1 views
4

Ces deux codes fournissent la même signature, qui devrait:signature m2crypto "algorithme"

code1:

from M2Crypto import RSA, EVP 
import base64, hashlib 

text = "some text" 

pkey = EVP.load_key("mykey.pem") #"mykey.pem" was generated as: openssl genrsa -des3 -out mykey.pem 2048 
pkey.sign_init() 
pkey.sign_update(text) 
signature = pkey.sign_final() 
print base64.b64encode(signature) 

code2:

pkey = RSA.load_key("mykey.pem") 
signature = pkey.sign(hashlib.sha1(text).digest()) 
print base64.b64encode(signature) 

Cependant, si je veux « imitez "l'algorithme de signature, c'est-à-dire le cryptage du résumé avec la clé privée, je reçois une signature différente, à savoir:

pkey = RSA.load_key("mykey.pem") 
signature = pkey.private_encrypt(hashlib.sha1(text).digest(), RSA.pkcs1_padding) 
print base64.b64encode(signature) #different from the two above 

Pourriez-vous s'il vous plaît fournir quelques explications? Quel est le problème avec la dernière façon de signer?

+0

Pouvez-vous également montrer vos importations? – Daenyth

+0

Bien sûr, désolé, j'ai ajouté les importations – michal

+0

FYI, je pense que [pycrypto] (http://www.dlitz.net/software/pycrypto/) est le [package crypto préféré] (http://stackoverflow.com/questions/1137874/recommended-python-cryptographic-module) pour Python ces jours-ci. – Keith

Répondre

3

Je crois que la différence est que RSA_sign signe le digest PKCS1 algorithmIdentifier avec les données de résumé, où RSA_private_encrypt ne signe que les données de résumé.

De la RSA_private_encrypt page man:

RSA_PKCS1_PADDING 
    PKCS #1 v1.5 padding. This function does not handle the 
    algorithmIdentifier specified in PKCS #1. When generating or 
    verifying PKCS #1 signatures, RSA_sign(3) and RSA_verify(3) should 
    be used. 
+0

Merci! Cela a certainement du sens. – michal

0

Qu'est-ce qui se passe en interne dans EVP.sign() est la suivante (par opposition à la plaine RSA.sign()):

sha1_hash = hashlib.sha1(MESSAGE).digest() 
# Add ASN.1 SHA-1 OID prefix 
sha1_asn1_prefix = '3021300906052b0e03021a05000414'.decode('hex') 
asn1_hash = sha1_asn1_prefix + sha1_hash 
rsa = RSA.load_key(KEY) 
# Use PKCS#1 padding 
signature = rsa.private_encrypt(asn1_hash, RSA.pkcs1_padding).encode('hex') 

Voir this answer pour des explications plus et this gist pour un exemple complet.

Mais la ligne de fond est que EVP.sign() doit être utilisé à la place que dans le code ci-dessus - il fait la bonne chose en interne.

Questions connexes