# [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:

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

PUBLIC KEY:
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.

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":

http://crypto.stanford.edu/~dabo/abstracts/RSAattack-survey.html

>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
>algo.

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:

http://lists.dlitz.net/pipermail/pycrypto/2008q3/000000.html
http://lists.dlitz.net/pipermail/pycrypto/2008q3/000020.html

I hope you find the above information helpful.

Cheers,
- 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
```