I am writing a small piece of code which reads public and private key stored in .pem file. I am using the following commands to generate the keys.
Below command to generate pair of key.
$openssl genrsa -out mykey.pem 2048
This command to generate the private key
$openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \
-out private_key.pem -nocrypt
and this command to get the public key.
$ openssl rsa -in mykey.pem -pubout -outform DER -out public_key.der
I have written two methods which reads the private key and public key respectively.
public PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
//System.out.println("Private key\n"+privKeyPEM);
Base64 b64 = new Base64();
byte [] decoded = b64.decode(privKeyPEM);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(spec);
}
public PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
Base64 b64 = new Base64();
byte [] decoded = b64.decode(publicKeyPEM);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePublic(spec);
}
I feel like this is a naive way of doing it. I couldn't get any better way of doing it over internet. Can anyone suggest me what is the best way of writing the same code to handle the generic cases. I don' want to use any kind of third party library.
I have very basic knowledge of singing/encrypting and hardly use any java security APIs. So if I am not making sense somewhere then please point out.
Java supports using DER for public and private keys out of the box (which is basically the same as PEM, as the OP asks, except PEM files contain base 64 data plus header and footer lines).
You can rely on this code (modulo exception handling) without any external library if you are on Java 8+ (this assumes your key files are available in the classpath):
For the record, you can convert a PEM key to a DER key with the following command:
And get the public key in DER with: