How to verify in pycrypto signature created by openssl?

Ivan picture Ivan · Jun 14, 2011 · Viewed 14.2k times · Source

I've created private/public key in openssl, and signed some data:

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
echo 'data to sign' > data.txt
openssl dgst -md5 < data.txt > hash
openssl rsautl -sign -inkey private.pem -keyform PEM -in hash  > signature

now in python, I'm trying to verify this data:

pubKey = open('public.pem').read()
data = open('data.txt').read()
signature = open('signature').read()

from Crypto import PublicKey
key = PublicKey.RSA.importKey(pubKey)
pub = key.publickey()
hash = MD5.new(data).hexdigest()
# here, hash is same, as contents of 'hash' file
print pub.verify(hash, signature) # <-- here

the problem is, that pub.verify expects second parameter to be one-element list with some large number. And I don't know how to convert binary data in file signature to this integer. Every example about pycrypto shows signature generated from pycrypto, and key.sign() generates correct signature in form (1832273432...2340234L, ). But I dont know how to use external signature.

If this is necessary, below are additional informations, which I don't exactly know how to interpret:

Brief technical information:

  • Format of digital signature: PKCS#7 “Signed-Data”
  • Public key procedure: DSS
  • Key length: 512 – 1024 bits
  • Public exponent: 2 +1
  • Public key format: X.509 v3 certificate
  • MD (Message Digest) algorithm: MD5 or RIPEMD-160 16

Answer

univerio picture univerio · May 13, 2012

The Crypto.Signature module is what you want. From the Crypto.Signature.PKCS1_v1_5 documentation:

key = RSA.importKey(open('pubkey.der').read())
h = SHA.new(message)
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
   print "The signature is authentic."
else:
   print "The signature is not authentic."