Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RSA cryptography between Python and Java

137 views
Skip to first unread message

Rob Knop

unread,
Jul 25, 2009, 2:57:55 PM7/25/09
to

I've created an RSA key in Java. I have exported the public key by
making it into a X509EncodedKeySpec and spitting out the result of
getEncoded().

I want to use this public key to encode something in python that I will
send to Java, and then decode in Java with the corresponding private
key.

Are there any python libraries that will take a public key in this
format and do RSA encoding on it?

--
--Rob Knop
E-mail: rk...@pobox.com
Home Page: http://www.pobox.com/~rknop/
Blog: http://www.sonic.net/~rknop/blog/

Paul Rubin

unread,
Jul 25, 2009, 3:01:07 PM7/25/09
to
Rob Knop <rk...@pobox.com> writes:
> Are there any python libraries that will take a public key in this
> format and do RSA encoding on it?

Try www.trevp.com/tlslite

Rob Knop

unread,
Jul 25, 2009, 4:08:17 PM7/25/09
to
Paul Rubin <http://phr...@NOSPAM.invalid> writes:

> www.trevp.com/tlslite

Thanks, but that looks like a library for setting up a secure connection
between two ends. What I need is the ability to encrypt with a public
key in Python, where that public key was generated in Java as described,
and where the cipertext can later be decrypted with the corresponding
secret key in Java.

Paul Rubin

unread,
Jul 25, 2009, 4:10:43 PM7/25/09
to
Rob Knop <rk...@pobox.com> writes:
> > www.trevp.com/tlslite
>
> Thanks, but that looks like a library for setting up a secure connection
> between two ends. What I need is the ability to encrypt with a public
> key in Python, where that public key was generated in Java as described,
> and where the cipertext can later be decrypted with the corresponding
> secret key in Java.

Yes, I think that library has the function that you want. It's just
X509 DER encoding.

Piet van Oostrum

unread,
Jul 27, 2009, 7:08:27 AM7/27/09
to
>>>>> Paul Rubin <http://phr...@NOSPAM.invalid> (PR) wrote:

>PR> Rob Knop <rk...@pobox.com> writes:
>>> Are there any python libraries that will take a public key in this
>>> format and do RSA encoding on it?

>PR> Try www.trevp.com/tlslite

I have looked into tlslite and found no easy way to do this. Maybe I
overlooked it. On the other hand with M2Crypto it isn't that hard.

However, M2Crypto wants to load keys in PEM format rather than the DER
format that the Java getEncoded() produces. It is not hard to convert
this to PEM format: just Base64 encode it and put a header and trailer
line around it. The conversion can be done with openssl or just on the
fly in the Python code.
Please note that the text to be encrypted must be smaller than the key
size (at least 11 bytes smaller). You shouldn't encrypt large data with
RSA anyway: it is too slow. Normally you would encrypt a session key
with RSA and encrypt the data with the session key using a symmetric
algorithms like AES.

Here is an example script:
If your OS doesn't have /dev/urandom you should probably seed OpenSSL's
PRNG to be more secure.
------------------------------------------------------------------------
from M2Crypto import BIO, RSA

pubkey = open("pubkey.der", 'rb').read()

import base64
pubkey = base64.encodestring(pubkey)
pubkey = '-----BEGIN PUBLIC KEY-----\n' + pubkey + '-----END PUBLIC KEY-----'

bio = BIO.MemoryBuffer(pubkey)
rsa = RSA.load_pub_key_bio(bio)

plaintext = "This is my secret text."

codetext = rsa.public_encrypt(plaintext, RSA.pkcs1_padding)

with open("codetext", 'wb') as out:
out.write(codetext)
------------------------------------------------------------------------
The following Java program decodes this with the corresponding private
key:
------------------------------------------------------------------------
import java.security.*;
import javax.crypto.*;
import java.security.spec.*;
import java.security.interfaces.*;
import java.io.*;

class Decrypt {

public static void main(String[] args) {

byte[] key = null;
try {
File file = new File("privkey.der");
FileInputStream keyfile = new FileInputStream(file);
key = new byte[(int)file.length()];
DataInputStream dis= new DataInputStream(keyfile);
dis.readFully(key);
dis.close();
}
catch(FileNotFoundException e)
{
System.out.println("Key file not found" + e);
}
catch (IOException e) {
System.out.println("Can't read key file" + e);
}

byte[] codetext = null;
try {
File file = new File("codetext");
FileInputStream codefile = new FileInputStream(file);
codetext = new byte[(int)file.length()];

DataInputStream dis = new DataInputStream(codefile);
dis.readFully(codetext);
dis.close();
}
catch(FileNotFoundException e)
{
System.out.println("Code file not found" + e);
}
catch (IOException e) {
System.out.println("Can't read code file" + e);
}

try {

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(key);
RSAPrivateKey rsakey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);

Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");

c.init(Cipher.DECRYPT_MODE, rsakey);
byte[] decrypted = c.doFinal(codetext);
System.out.println("Decrypted text:");
System.out.println(new String(decrypted));

}
catch (NoSuchAlgorithmException e) {
System.out.println("Wrong Algorithm " + e);
}
catch (InvalidKeyException e) {
System.out.println("Invalid key " + e);
}
catch (IllegalBlockSizeException e) {
System.out.println("Illegal block size" + e);
}
catch (NoSuchPaddingException e) {
System.out.println("Illegal padding " + e);
}
catch (BadPaddingException e) {
System.out.println("Bad padding " + e);
}
catch (InvalidKeySpecException e) {
System.out.println("Invalid keyspec " + e);
}
}
}
------------------------------------------------------------------------
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: pi...@vanoostrum.org

Michael Ströder

unread,
Jul 27, 2009, 7:35:15 AM7/27/09
to
Piet van Oostrum wrote:
> Please note that the text to be encrypted must be smaller than the key
> size (at least 11 bytes smaller). You shouldn't encrypt large data with
> RSA anyway: it is too slow. Normally you would encrypt a session key
> with RSA and encrypt the data with the session key using a symmetric
> algorithms like AES.

I'd use CMS (AKA PKCS#7) for encrypted/signed data with X.509 certs. One
should not invent another message format.

Ciao, Michael.

--
Michael Str�der
E-Mail: mic...@stroeder.com
http://www.stroeder.com

Piet van Oostrum

unread,
Jul 27, 2009, 8:19:49 AM7/27/09
to
>>>>> Michael Str�der <mic...@stroeder.com> (MS) wrote:

>MS> Piet van Oostrum wrote:
>>> Please note that the text to be encrypted must be smaller than the key
>>> size (at least 11 bytes smaller). You shouldn't encrypt large data with
>>> RSA anyway: it is too slow. Normally you would encrypt a session key
>>> with RSA and encrypt the data with the session key using a symmetric
>>> algorithms like AES.

>MS> I'd use CMS (AKA PKCS#7) for encrypted/signed data with X.509 certs. One
>MS> should not invent another message format.

Yes but the original question was not about X.509 certs. Just the RSA
public key. I don't know what the OP wants to do with it.

M.-A. Lemburg

unread,
Jul 28, 2009, 3:30:23 AM7/28/09
to Rob Knop, pytho...@python.org
Rob Knop wrote:
> I've created an RSA key in Java. I have exported the public key by
> making it into a X509EncodedKeySpec and spitting out the result of
> getEncoded().
>
> I want to use this public key to encode something in python that I will
> send to Java, and then decode in Java with the corresponding private
> key.
>
> Are there any python libraries that will take a public key in this
> format and do RSA encoding on it?

M2Crypto will let you do this:

http://chandlerproject.org/bin/view/Projects/MeTooCrypto

If you have access to the raw key data (instead of having it
encoded in a X509 certificate), then you can also use PyCrypto,
which does require setting up OpenSSL first:

http://www.dlitz.net/software/pycrypto/

--
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source (#1, Jul 28 2009)
>>> Python/Zope Consulting and Support ... http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611
http://www.egenix.com/company/contact/

0 new messages