Generate public key and private key with OpenSSL in Windows 10

Read RSA Private Key Java: algid parse error, not a sequence

This tutorial guides you on how to resolve Error InvalidKeySpecException : algid parse error, not a sequence while reading pem to get RSA private key in Java.

InvalidKeySpecException : algid parse error, not a sequence

Are you facing the the following error while reading RSA private key from private.pem file with Java code ?

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)
	at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390)
	at com.sneppets.util.PemToPublicPrivateKeyExample1.getPrivateKey(PemToPublicPrivateKeyExample1.java:63)
	at com.sneppets.util.PemToPublicPrivateKeyExample1.main(PemToPublicPrivateKeyExample1.java:27)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350)
	at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)
	at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:130)
	at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:80)
	at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:356)
	at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:247)
	... 3 more

I got the above error when I tried to get private and public keys from .pem files. I had generated keypairs with OpenSSL using the following commands.

> openssl genrsa -out private.pem 2048
> openssl rsa -in private.pem -outform PEM -pubout -out public.pem

Then I wrote the following Java classes PemFile.java and PemToPublicPrivateKeyExample.java.

PemFile.java

This util class used to handle pem file I/O operations and this uses BouncyCastle library

package com.sneppets.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

public class PemFile {
	
	private PemObject pemObject;
	 
	public PemFile(String filename) throws FileNotFoundException, IOException {
		PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream(filename)));
		try {
			this.pemObject = pemReader.readPemObject();
		} finally {
			pemReader.close();
		}
	}
 
	public PemObject getPemObject() {
		return pemObject;
	}

}

PemToPublicPrivateKeyExample.java

This is the actual demo class which was used to read .pem file to get the private and public keys.

package com.sneppets.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class PemToPublicPrivateKeyExample {
	
	public static void main (String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
		
		RSAPublicKey publicKey = (RSAPublicKey) getPublicKey("public.pem");
		System.out.println("Public Key: " + publicKey);
		
		RSAPrivateKey privateKey = (RSAPrivateKey) getPrivateKey("private.pem");
		System.out.println("Private Key: " + privateKey);
	}
	
	private static PublicKey getPublicKey(String filename) throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		
		//Usage of PemFile.java util
		PemFile pemFile = new PemFile(filename);
		byte[] encoded = pemFile.getPemObject().getContent();  
		
	    X509EncodedKeySpec  keySpec = new X509EncodedKeySpec(encoded);
	    KeyFactory kf = KeyFactory.getInstance("RSA");	  
	    PublicKey publicKey = kf.generatePublic(keySpec);
	    return publicKey;
	}
	
	private static RSAPrivateKey getPrivateKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		
   
		PemFile pemFile = new PemFile(filename);
		byte[] encoded = pemFile.getPemObject().getContent(); 
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(spec);
        
        return privateKey;

	}

}

When I tried to run the above program, it resulted with following output with error InvalidKeySpecException : algid parse error, not a sequence. It looks like there is a problem with KeySpec. It means that your key is not in the PKCS#8 format.

Output

Public Key: Sun RSA public key, 2048 bits
  params: null
  modulus: 25622523552640509872674647748128418427196878805802974525582213375943292866688386280128572938417498583760725631884402047650172578686271723723912330821024381216453489466722940584464191109827782366140686281989329115496275295815310414943283528008535270516589906407988761155150211830876162901079773987287320522395702055867191390238620531771664622250346650503605006931286353348714961829467079593192943673984151097109814014569056365504907110936637707839047313988149249985540404575244379812342259482507954431540160866546667721354659887420139015654844886782367838366698828795807906696509716076522708156260850256749742657872987
  public exponent: 65537
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)
	at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390)
	at com.sneppets.util.PemToPublicPrivateKeyExample1.getPrivateKey(PemToPublicPrivateKeyExample1.java:63)
	at com.sneppets.util.PemToPublicPrivateKeyExample1.main(PemToPublicPrivateKeyExample1.java:27)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350)
	at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)
	at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:130)
	at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:80)
	at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:356)
	at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:247)
	... 3 more

Solved: algid parse error, not a sequence

Now, let’s see how to solve the above error. What you need to do is ? Try to run the following command, that will output private key in DER format which Java code can read with the help of  “PKCS8EncodedKeySpec” interface.

> openssl pkcs8 -topk8 -inform PEM -outform DER -in private.pem -out private.der -nocrypt

Then rewrite your main() method and getPrivateKey() method as shown below.

public static void main (String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
		
    RSAPublicKey publicKey = (RSAPublicKey) getPublicKey("public.pem");
    System.out.println("Public Key: " + publicKey);
		
    RSAPrivateKey privateKey = (RSAPrivateKey) getPrivateKey("private.der");
    System.out.println("Private Key: " + privateKey);
}

And your getPrivateKey() method should look like the below one.

private static RSAPrivateKey getPrivateKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		
    File file = new File(filename);
    FileInputStream fis = new FileInputStream(file);
    DataInputStream dis = new DataInputStream(fis);
        
    byte[] keyBytes = new byte[(int) file.length()];
    dis.readFully(keyBytes);
    dis.close();
        
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(spec);
        
    return privateKey;

}

After you make the above modifications when you run the java class PemToPublicPrivateKeyExample.java you should get the following output. The error algid parse error, not a sequence is gone away.

Public Key: Sun RSA public key, 2048 bits
  params: null
  modulus: 25622523552640509872674647748128418427196878805802974525582213375943292866688386280128572938417498583760725631884402047650172578686271723723912330821024381216453489466722940584464191109827782366140686281989329115496275295815310414943283528008535270516589906407988761155150211830876162901079773987287320522395702055867191390238620531771664622250346650503605006931286353348714961829467079593192943673984151097109814014569056365504907110936637707839047313988149249985540404575244379812342259482507954431540160866546667721354659887420139015654844886782367838366698828795807906696509716076522708156260850256749742657872987
  public exponent: 65537
Private Key: SunRsaSign RSA private CRT key, 2048 bits
  params: null
  modulus: 25622523552640509872674647748128418427196878805802974525582213375943292866688386280128572938417498583760725631884402047650172578686271723723912330821024381216453489466722940584464191109827782366140686281989329115496275295815310414943283528008535270516589906407988761155150211830876162901079773987287320522395702055867191390238620531771664622250346650503605006931286353348714961829467079593192943673984151097109814014569056365504907110936637707839047313988149249985540404575244379812342259482507954431540160866546667721354659887420139015654844886782367838366698828795807906696509716076522708156260850256749742657872987
  private exponent: 17586675877266705152852948405542832996789557033758566963459796821491022521968409906450151769059223626246375651907411955222968904695737689370473905996950420987529598801922548122601777754449900577934700871610326862724399219245008291429173183703983125160562182583129506126953049098803766357618924779439790333077672652416920933916743021966806362551647245303270227184263417966975663222400220534187827685721381511872771004877660769860453663015783027855746470790262266367515875656740848222390555559390660055912124446014837715667235277503335371191622760609500597616829812723390081370845708118008488655826516816751198273129617

That’s it. Hope it helped 🙂

Also See:

References:

 

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments