I want to generate the private key from a string(a .pem
file) in Java.
private static final String test = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
"-----END RSA PRIVATE KEY-----";
try {
String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
byte [] encoded = Base64.decode(privKeyPEM);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(keySpec);
}
catch (Exception e) {
e.printStackTrace();
}
The last line(generatePrivate function) is throwing this exception:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at Test.main(Test.java:52)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
... 3 more
If I change the private key to the value from a .der
file it works properly, but I need to generate the private key file from a .pem
file.
I attached a screenshot of the bytes printed as string(once hard-coded with \n and once hard-coded without \n) and once from the file.
The weird thing is that the output from the file is different to the output from the strings.
If I try to encode a .der
file with Base64, the result is different than the string in the .pem
file. Why is that so?
You say that the last line is throwing exception, i.e.
PrivateKey privKey = kf.generatePrivate(keySpec);
Above line works on keyspecs being set correct, i.e.
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
So actual problem is with encoded bytes array. Have you done System.out after byte [] encoded = Base64.decode(privKeyPEM);
and see what the output is.
I understand that if the message is in MIME format, then after certain characters it appends a combination of carriage return and newline so the strings are not too long for e-mail system or wherever you are using it.
The final String test has some '\n' in the original text which you use. You did get rid of other text in below line,
String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
But, look at the string,
"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
"-----END RSA PRIVATE KEY-----";
it may have some more '\n' left which may result in some unwanted characters when you generate keyspec. Try more System.out and see what the encoded byte array is like and also before that check String privKeyPEM and see if any extra character is not left in it.
Hope this hepls.