[pycrypto] PyCrypto AND Crypt_RSA integration

Dwayne C. Litzenberger dlitz at dlitz.net
Tue Feb 10 18:32:53 CST 2009

On Mon, Feb 09, 2009 at 10:36:40AM -0200, Mauricio Arozi wrote:
>Am I helpless?

I think the problem is that you're asking the mailing list for the *Python* 
Cryptography Toolkit about how to use an obscure *PHP* library.

We can help with the Python side of things.  I wouldn't expect the people 
here to know and/or care much about PHP.

> According to this site: http://pajhome.org.uk/crypt/rsa/rsa.html, and
> yet others, the e(exponent?) is used for the public key, and d for the
> private key.

The notation I've seen most often is something like this:

     n - modulus (public)
     e - public exponent
     d - private exponent
     (n, e) - public key
     (n, d) - private key
     (p, q) - the (private) primes from which the keypair is derived.

PyCrypto uses a similar notation:

     from Crypto.PublicKey import RSA
     import os

     # DO NOT USE RandomPool (see below)
     keypair = RSA.generate(2048, os.urandom)

     print "PRIVATE KEYPAIR:"
     print "n:", keypair.n   # modulus (public)
     print "e:", keypair.e   # public exponent
     print "d:", keypair.d   # private exponent
     print "p:", keypair.p   # prime (private)
     print "q:", keypair.q   # other prime (private)
     print "u:", keypair.u   # I forget what this for (but it's private)

     pub = keypair.publickey()
     print ""
     print "PUBLIC KEY:"
     print "n (pub):", pub.n     # modulus (public)
     print "e (pub):", pub.e     # public exponent
     print "d (pub):", pub.d     # raises an exception
     print "p (pub):", pub.p     # raises an exception
     print "q (pub):", pub.q     # raises an exception
     print "u (pub):", pub.u     # raises an exception

This outputs the following:

     n: 277...[truncated]
     e: 65537
     d: 232...[truncated]
     p: 159...[truncated]
     q: 174...[truncated]
     u: 125...[truncated]

     n (pub): 277...[truncated]
     e (pub): 65537
     d (pub):
     Traceback (most recent call last):
       File "x.py", line 21, in ?
         print "d (pub):", pub.d
       File "/usr/lib/python2.4/site-packages/Crypto/PublicKey/RSA.py", line 154, in __getattr__
         return getattr(self.key, attr)
     AttributeError: rsaKey instance has no attribute 'd'

> My problem is that while using PyCrypto to generate both public and 
> private keys, the e(exponent?) is always the same.

Mads Kiilerich already talked a bit about this, but I won't go into detail.  
What you're describing here is normal, and it really helps improve the 
performance of encryption/verification.

If you're concerned about the security of using RSA, I suggest reading Dan 
Boneh's 1999 article, "Twenty years of attacks on the RSA cryptosystem":


>So in simple words, I only need to be able to encrypt/decrypt sign and 
>verify signs on php and python, simultaneously, if possible, using RSA 

PyCrypto's PublicKey package is very low-level, so people shouldn't use it 
directly unless they REALLY know what they are doing.  Mere mortals should 
use a separate library in addition to PyCrypto for that.  You should never 
do anything like this:

>privkeyA = RSA.generate(512, rpool.get_bytes)
>pubkeyA = privkeyA.publickey()
>msg = 'This is the secret phrase testing.'
>msgc = pubkeyA.encrypt(msg, '')

That is called "textbook RSA", and it's insecure.  (Also, it uses a 512-bit   
key, which is way too short, but I assume that's just for demonstration.)  
I strongly recommend looking at PKCS#1v2 (also known as RSAES-OAEP).  
PyCrypto doesn't include an implementation yet, but Sergey Chernov 
mentioned that he is working on one.

Also, I noticed in your code that you used RandomPool.  Don't.  RandomPool 
is a security disaster, and it will be removed from future versions.  See 
the following messages:


I hope you find the above information helpful.

  - Dwayne

Dwayne C. Litzenberger <dlitz at dlitz.net>
  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
  Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9  179F 1C11 B877 E780 4B45

More information about the pycrypto mailing list