Crypto.PublicKey RSA Keysize off by one?
Question: 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'))
    


Answer: 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()](https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-
class.html#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
<http://security.stackexchange.com/q/44702>.

