111

When trying to read a RSA private key from a file using the method

public PrivateKey getPrivateKey()
        throws NoSuchAlgorithmException,
        InvalidKeySpecException, IOException {

    final InputStream inputStream = getClass().getClassLoader()
                    .getResourceAsStream("privatekey");
    byte[] privKeyBytes = null;
    try {
        privKeyBytes = IOUtils.toByteArray(inputStream);
    } catch (final IOException exception) {
        LOGGER.error("", exception);
        IOUtils.closeQuietly(inputStream);
    }

    LOGGER.debug("privKeyBytes: {}", privKeyBytes);

    String BEGIN = "-----BEGIN RSA PRIVATE KEY-----";
    String END = "-----END RSA PRIVATE KEY-----";
    String str = new String(privKeyBytes);
    if (str.contains(BEGIN) && str.contains(END)) {
        str = str.substring(BEGIN.length(), str.lastIndexOf(END));
    }

    KeyFactory fac = KeyFactory.getInstance("RSA");
    EncodedKeySpec privKeySpec =
            new PKCS8EncodedKeySpec(Base64.decode(str.getBytes()));
    return fac.generatePrivate(privKeySpec);
}

I get the exception

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:200) ~[na:1.6.0_23]
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:342) ~[na:1.6.0_23]

at the fac.generatePrivate(privKeySpec) call.

What does this error mean?

Thanks

Dmitri

Glory to Russia
  • 17,289
  • 56
  • 182
  • 325

3 Answers3

153

I was having this same issue, and the format of the key was NOT the actual problem.
All I had to do to get rid of that exception was to call

java.security.Security.addProvider(
         new org.bouncycastle.jce.provider.BouncyCastleProvider()
);


and everything worked

Dimitris
  • 3,975
  • 5
  • 25
  • 27
102

It means your key is not in PKCS#8 format. The easiest thing to do is to use the openssl pkcs8 -topk8 <...other options...> command to convert the key once. Alternatively you can use the PEMReader class of the Bouncycastle lightweight API.

yegor256
  • 102,010
  • 123
  • 446
  • 597
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • 53
    Thanks, it worked. Here's the command: openssl pkcs8 -topk8 -nocrypt -in myrsakey.pem -out myrsakey_pcks8 – Glory to Russia Jul 03 '11 at 12:13
  • if it is not in PKCS8 format, what format it can be? If multiple options it can be, how to know the format before converting to PKCS8 using OPENSSL command? – Satish Patro Sep 07 '20 at 04:57
  • 5
    @PSatishPatro: The private key was in PKCS#1 format. In this case the clue was the "-----BEGIN RSA PRIVATE KEY-----" which signals this is a PKCS#1 private in "PEM" format. – President James K. Polk Sep 07 '20 at 12:41
84

You must make your PCKS8 file from your private key!

private.pem => name of private key file

openssl genrsa -out private.pem 1024

public_key.pem => name of public key file

openssl rsa -in private.pem -pubout -outform PEM -out public_key.pem

‫‪private_key.pem‬‬ => name of private key with PCKS8 format! you can just read this format in java

openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt
Community
  • 1
  • 1
Pasha
  • 1,534
  • 15
  • 27
  • 11
    This was my problem - the file was generated using `genrsa` which creates a PKCS#1 format (this is the format the OP loads, as can be seen by the `BEGIN RSA PRIVATE KEY` header), while PKCS#8 is a different format (and in PEM encoding can be detect due to the different header: `BEGIN PRIVATE KEY`). My key generator now looks like this: `openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out private.pem` – Guss Jan 10 '18 at 18:34
  • Do you have a similar key generator for EC private key? – Rahul Agrawal Jan 19 '18 at 17:17
  • @RahulAgrawal, unfortunately, don't have – Pasha Nov 02 '19 at 08:43
  • What about the public key ? Will it be in PKCS#8 format by default ? – Sai Ram Reddy Feb 12 '20 at 14:46
  • @SaiRamReddy "-outform PEM" sets output format, take a look at documentation: https://www.openssl.org/docs/man1.0.2/man1/openssl-rsa.html – Pasha Feb 13 '20 at 09:49
  • Is it possible to generate the same programatically? I would want to do the same programatically instead of using CLI. – Shivam Sahil Oct 26 '22 at 11:02
  • @ShivamSahil indeed possible! but the parameters should be handled. here is a sample code: https://www.example-code.com/java/rsa_genKey.asp – Pasha Nov 03 '22 at 12:36