How to get back a signed string (e.g. md5 hash) using a public-key (x509 certificate)
Question: I'm very new with cryptographic and stuck for 2 days with this problem, I hope
you can help me with.

I try to sign a md5 digest string with the private key of a X509 certificate.
As far as I can see, this works fine. Now I try to get back that string using
the public key of that x509 certificate, but I have no idea how to do this.

First I created a x509 certificate and a private-Keyfile using OpenSSL:

openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem

Here's the example code I tried:

    
    
    import M2Crypto
    import hashlib
    
    def empty_callback ():
     return
    
    # md5 hash of params
    params = "0045KIABCDEFG"
    
    m = hashlib.md5()
    m.update(params)
    md = m.digest()
    print m.hexdigest()
    
    M2Crypto.Rand.rand_seed (os.urandom (1024))
    
    # sign md5 hash with private key
    SignEVP = M2Crypto.EVP.load_key ('privkey.pem')
    #Begin signing
    SignEVP.sign_init ()
    #Tell it to sign our string
    SignEVP.sign_update (md)
    #Get the final result
    StringSignature = SignEVP.sign_final ()
    #print the final result
    print StringSignature.encode ('base64')
    

I get the public key with this, but don't know how to use it then.

objX509 = M2Crypto.X509.load_cert ('signer.pem') PubKey = objX509.get_pubkey()

I only found how to verify the signed string, but that's not what I need. Is
there a method to get back the origin md5 digest (md) by using the signer.pem
(the public key)?

I'm using M2Cyrpto-0.21.1 and OpenSSL 1.0.0d, and programming with Python27,
32bit on Windows7.

kind regards, Falko


Answer: Technically, you are not supposed to "decrypt" the signature. If you really
want to decrypt it, do something like this:

    
    
    cert = X509.load_cert("signer.pem")
    decrypted = cert.get_pubkey().get_rsa().public_decrypt(StringSignature, 1)
    

but this will not give you what you are expecting, I guess.

If you want to pull out the message digest that was signed using the code
above, you would have to decode the ASN.1 sequence in the `decrypted`. You can
do this with PyCrypto, of course, but what for?

    
    
    from Crypto.Util import asn1
    seq = asn1.DerSequence()
    seq.decode(decrypted)
    obj = asn1.DerObject()
    obj.decode(seq[1])
    # now this is the original message digest that was signed
    original_message_md = obj.payload
    

