Loading a PKCS#1 public key using M2Crypto

Piet van Oostrum piet at vanoostrum.org
Thu Jan 17 11:39:57 EST 2013


Piet van Oostrum <piet at vanoostrum.org> wrote:

> Converting to X.501 isn't difficult (assuming this is a 2048 bit key):
> Get rid of the 'RSA' in header and trailer
> Prepend X.501 header 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' to the data
> Reformat the lines to 64 characters.

This solution is a bit restricted as it only works if the key is 2048
bits and uses an exponent of 65537 (which is the default). Otherwise it
fails.

Here is a robust solution that works for all PKCS#1 keys. Instead of
using a fixed X.501 header it calculates the header. We could do a
complete ASN.1 encoding, but most of the parts are fixed. The only
variable parts are two length fields. So I just plug these into the
fixed stuff. This saves using one of the ASN.1 libraries. We do have to
work in binary (DER format) instead of base64, however.

from M2Crypto import BIO, RSA
import base64

def der_length(length):
    """DER encoding of a length"""
    if length < 128:
        return chr(length)
    prefix = 0x80
    result = ''
    while length > 0:
        result = chr(length & 0xff) + result
        length >>= 8
        prefix += 1
    return chr(prefix) + result
    
pubkey="""-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEApwotnfHT9RAmxnuaGEMdI3lYPYE4aaqSD9v4KbTh1E7Le3GNJQb7
wCpmDe8+n8S5Kp/gBEpWiYuvsVA/T4KseoX7NMcacP+DJMwjmNd9U58USn2vLz0Z
TMtXpc/FUhW5PZdgCiuNzw6IFgGn9ZCCv85jjUIW3KD8fUNdrUfVSv4olDoL9NkR
dTRg3Os/znC6l0gv/mqnLaqj2bJ/tx47kUmj6Oq13JuEq34T+DVmsUCFVundQnRp
c/vVEqQot7Rvj9UmSvTi4WKt/qxiAnyZf3gXOdrXvxfVTGzD5I/Xg+By+a4C2JwB
A5RGvZP3fyfhkCnnhFDpfws5lc20FA6ryQIDAQAB
-----END RSA PUBLIC KEY-----
"""

pk = pubkey.split('\n')
pk = '\0' + base64.decodestring("".join(pk[1:-2]))
pk = '\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03' + \
     der_length(len(pk)) + pk
pk = '\x30' + der_length(len(pk)) + pk
pk = '-----BEGIN PUBLIC KEY-----\n' + base64.encodestring(pk) + '-----END PUBLIC KEY-----'

bio = BIO.MemoryBuffer(pk)
key = RSA.load_pub_key_bio(bio)

-- 
Piet van Oostrum <piet at vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]



More information about the Python-list mailing list