How do you verify an RSA SHA1 signature in Python? How do you verify an RSA SHA1 signature in Python? python python

How do you verify an RSA SHA1 signature in Python?


Use M2Crypto. Here's how to verify for RSA and any other algorithm supported by OpenSSL:

pem = """-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srWnUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrlXnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkealVvXw13PLINE/YptjkQIDAQAB-----END PUBLIC KEY-----""" # your example keyfrom M2Crypto import BIO, RSA, EVPbio = BIO.MemoryBuffer(pem)rsa = RSA.load_pub_key_bio(bio)pubkey = EVP.PKey()pubkey.assign_rsa(rsa)# if you need a different digest than the default 'sha1':pubkey.reset_context(md='sha1')pubkey.verify_init()pubkey.verify_update('test  message')assert pubkey.verify_final(signature) == 1


The data between the markers is the base64 encoding of the ASN.1 DER-encoding of a PKCS#8 PublicKeyInfo containing an PKCS#1 RSAPublicKey.

That is a lot of standards, and you will be best served with using a crypto-library to decode it (such as M2Crypto as suggested by joeforker). Treat the following as some fun info about the format:

If you want to, you can decode it like this:

Base64-decode the string:

30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb743366a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b63910203010001

This is the DER-encoding of:

   0 30  159: SEQUENCE {   3 30   13:   SEQUENCE {   5 06    9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)  16 05    0:     NULL            :     }  18 03  141:   BIT STRING 0 unused bits, encapsulates {  22 30  137:       SEQUENCE {  25 02  129:         INTEGER            :           00 DF 1B 82 2E 14 ED A1 FC B7 43 36 6A 27 C0 63            :           70 E6 CA D6 9D 41 16 CE 80 6B 3D 11 75 34 CF 0B            :           AA 93 8C 0F 8E 45 00 FB 59 D4 D9 8F B4 71 A8 D0            :           10 12 D5 4B 32 24 41 97 C7 43 4F 27 C1 B0 D7 3F            :           A1 B8 BA E5 5E 70 15 5F 90 78 79 CE 9C 25 F2 8A            :           9A 92 FF 97 DE 16 84 FD AF F0 5D CE 19 6A E7 68            :           45 F5 98 B3 28 C5 ED 76 E0 F7 1F 6A 6B 74 48 F0            :           86 91 E6 A5 56 F5 F0 D7 73 CB 20 D1 3F 62 9B 63            :           91 157 02    3:         INTEGER 65537            :         }            :       }            :   }

For a 1024 bit RSA key, you can treat "30819f300d06092a864886f70d010101050003818d00308189028181" as a constant header, followed by a 00-byte, followed by the 128 bytes of the RSA modulus. After that 95% of the time you will get 0203010001, which signifies a RSA public exponent of 0x10001 = 65537.

You can use those two values as n and e in a tuple to construct a RSAobj.


A public key contains both a modulus(very long number, can be 1024bit, 2058bit, 4096bit) and a public key exponent(much smaller number, usually equals one more than a two to some power). You need to find out how to split up that public key into the two components before you can do anything with it.

I don't know much about pycrypto but to verify a signature, take the hash of the string. Now we must decrypt the signature. Read up on modular exponentiation; the formula to decrypt a signature is message^public exponent % modulus. The last step is to check if the hash you made and the decrypted signature you got are the same.