简体   繁体   中英

How to generate RSA Private key from *pem string in Java

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.

Bigger Image

产量

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, ie

PrivateKey privKey = kf.generatePrivate(keySpec);

Above line works on keyspecs being set correct, ie

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM