
Generate the RSA keys
Open your favourite Linux and make sure you have openSSL installed.
Generate the private and public key. The public key is used by any interested senders, to use for encryption. The private key must be kept, surprise, private and is used to decrypt. Write this in the linux command line:
openssl genrsa -out private.pem 1024
Now you got a private key called private.pem.
You need to generate the public key from the private key, as we want to use it in Java we generate it as der instead of pem, its much easier to load into Java.
Now write the following to get a public key in der format:
openssl rsa -in private.pem -pubout -outform DER -out public_key.der
Now you got a public key called public_key.der ready to load into Java.
Useful information
If you want to see the information in the private key use this line:
openssl rsa -in private.pem -noout -text
The modulus is the public key. Please note, it can be padded with a 0, giving 1 byte more than the key size.
The public exponent is usually 65537 – not all tools let you change this.
The privateExponent is the private key. In our case we needed the private key inside an embedded system, we just copied the bytes from the private Exponent and used that in an appropriate RSA algorithm in the embedded device (remember to use same public exponent there). If you need help in getting RSA to work in an embedded system feel free to contact me.
A side note, if you are not familiar with RSA. The data you want to encrypt must be same size as your key. Some padding schemes exist, where data is padded, in some cases you can use less data.
If you want to generate a public pem key, use this line in linux:
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
If you want to encrypt some string (must be same size as the key, this example does not use padding):
cat text.txt | openssl rsautl -raw -encrypt -pubin -inkey public.pem > encrypted.txt
To decrypt use this line:
openssl rsautl -raw -decrypt -in encrypted.txt -out decrypted.txt -inkey private.pem
A few words on the key length
Please do not use less than 512 bits key size. 256 bit keys takes less than 30 minutes to crack on a standard desktop pc. Java does not allow you to use key sizes less than 256 bits, but you might find other algorithms that do not care. A rule of thumb is that if you want it totally uncrackable, you need 2048 bits, if you want it very secure use 1024 bits and if you want it ok secure, 512 bits are ok. But never less.
Encrypt the stuff in Java
Its pretty easy, just use the code below. Its almost trivial to write similar code for encryption.
package RSAHelper;
import java.security.*;
import java.io.*;
import java.security.spec.*;
import javax.crypto.Cipher;
public class RSAHelperPlain {
public PublicKey loadPubKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
File file = new File(filename);
int fileLength = (int)file.length();
DataInputStream dis = new DataInputStream(new FileInputStream(file));
byte[] keyBytes = new byte[fileLength];
dis.readFully(keyBytes);
dis.close();
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public byte[] encrypt(byte[] bs, PublicKey key) throws NoSuchAlgorithmException, GeneralSecurityException {
byte[] cipherText = null;
final Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(bs);
return cipherText;
}
}
To conclude it can be quite overwhelming, if you are not used to crypto work. Not all tutorials out there makes it easier to grasp the idea. But its is in fact quite simple.