user3810604
user3810604

Reputation: 31

Crypto.PublicKey RSA Keysize off by one?

I am trying to write a simple python method using Crypto.PublicKey.RSA that returns the size of an RSA public key, but the number returned is always the number I expect minus 1.

For example I give it a 1024-bit key and the number I get back from the size() function is 1023. I give it a 768-bit key and the number I get back is 767.

What am I missing here?

Results of the code below: I would expect this to return 1024: 1023

POC Python2 code:

#!/usr/bin/python2

from Crypto.PublicKey import RSA
from base64 import b64decode

def computeRSAStrength(pubkey,verbose=None):
    """Compute and return RSA key strength given a public key"""
    #TODO: add base64 validation on pubkey

    #Format key and use python crypto libs to determine key strength
    keyDER = b64decode(pubkey)

    try:
        #IMPORTANT PART
        keyPub = RSA.importKey(keyDER)
        keySize = int(keyPub.size()) #+ 1 ??? WHY DOES THIS RETURN (expected - 1) ???
        #END IMPORTANT PART

    except ValueError, e:
        if verbose:
            print 'ValueError Exception: {}'.format(e)
        keySize = 0

    # ALTERNATE METHOD?: use import os and make a syscall to openssl

    if verbose:
        print ' - Key in PEM format:'
        print keyPub.exportKey('PEM')

    return keySize


if __name__ == '__main__':

    print 'I would expect this to read 1024: '+str(computeRSAStrength('MIGfMA0GCSqGSIb3DQEBA'+
        'QUAA4GNADCBiQKBgQDLM0fpK/rhklYDRJSBQ6bSyZKjQxTeEnZywzodwGAjAste2aOQzXJyZmZrjHZ'+
        '0JL6Gy/e351n1P0Yo0cVE4nEQ7WD9jo0cqVEmkf1SInnhN1FGX/pOTjrjh7QU398YFxks/rqnX6C1q'+
        'doeu7B4wwRhNEHUjlaH79afYqOtk0ta0wIDAQAB'))

Upvotes: 3

Views: 729

Answers (1)

mhawke
mhawke

Reputation: 87084

I'm not sure that _RSAobj.size() refers to the actual size of the key. It's a bit vague but the documentation for size() states this:

size(self)

Tell the maximum number of bits that can be handled by this key.

Returns:
    int
Overrides: pubkey.pubkey.size
    (inherited documentation) 

I'm unsure, but it might actually mean the maximum number of plaintext bits that can be handled by crypto operations (although you can encrypt up to 128 bytes/ 1024 bit of plaintext). The code explicitly subtracts one from the number of bits in the modulus, so it is safe to add one to size() to get the modulus size.

There is some seemingly related information at https://security.stackexchange.com/q/44702.

Upvotes: 2

Related Questions