120

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

4 Answers 4

170

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

Sign up to request clarification or add additional context in comments.

9 Comments

How does this fix the issue?
It works...but why?!
How does this magic work? 0_o
What is the magic behind this?
Wow thank you time saver! I added following dependancy to get the BouncyCastleProvider: <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
|
114

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.

3 Comments

Thanks, it worked. Here's the command: openssl pkcs8 -topk8 -nocrypt -in myrsakey.pem -out myrsakey_pcks8
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?
@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.
90

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

7 Comments

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
Do you have a similar key generator for EC private key?
@RahulAgrawal, unfortunately, don't have
What about the public key ? Will it be in PKCS#8 format by default ?
@SaiRamReddy "-outform PEM" sets output format, take a look at documentation: openssl.org/docs/man1.0.2/man1/openssl-rsa.html
|
0

I faced a similar issue in Spring Boot REST API. I was calling DocuSign APIs from Spring Boot code. It was working fine in the local environment but after deploying the war file in Tomcat 9 server, it started throwing an error:

java.security.InvalidKeyException: IOException : algid parse error, not a sequence

Then I restarted the Tomcat service, and it started working as expected. Maybe Tomcat failed to load BouncyCastleProvider into the classpath.

I hope this will be helpful to someone who visits this question in the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.