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