InvalidKeySpecException : algid parse error, not a sequence
Your private key is not in PKCS#8 format. You have to add key algorithm information to it to make it PKCS#8 and then it will work.
Probably you should alter the way you generate keys to have them in PKCS#8 format. But since I know nothing on that I will just show how to update key to it in your application using BouncyCastle library:
@Test
public void testKey() throws Exception {
String privKeyStr = "MIICXQIBAAKBgQCE3pA746UfpC8sFk8ZJp0yupyJqj5jy6cjdxUYoP7mCm7c0mqQDeCcDNBYW2eSozCioPrH/9L+CDQEPLYakoem+jFnUKDH5+pru/0PJTJJF8Xh/ZT9eJlvsYBr1/qSfICf6RTs7kzwq9IuSZBw7/tfNEF9i0A8FVox6HOopXod1QIDAQABAoGANOFrYBqK5lvu1koOswDWQZFZqcSSzh8IZyoGwGWa7S0r0EECXlDXmuPSq8e9IfRG8ALHrH+ZlrbnFOSgyVSWHfpj3aH+qknoSX5TW2rMQHih8865xuqheMQ+RTZ7+BRDqNsYkzxB/Z8mqzpoJQSYf+H7nWxdDCgAJVYZzxl3DmUCQQD32iEjnwiwUjii8slcmvCEZl+z84DWNdvJOg6Z38sI4AvrfpKc1WAcDg1rNZCKrRgokh54wpLt08cpFcrD04c3AkEAiTzDmc0bdgfg5wj6xHFZpYlBwiGm/bjOR2PS57P0GNU5PsDllRbFqIuzArITutO5lvZZImzuYz7Lf+cQ73pxUwJBAOdEwmdaneDo17A0m2+to3/nhqWDMVSwLMU3RyiNigZeCMFU+bkd4PBMrHi9IoJDwacZsRU9eZwxYEUV8H2Jg0ECQEEkOqRSm2pXKwX/WSjNtQPCNxhy6NUeV6vDUmTxIjh3XYjP/ynZeVEbnoj1BjB0N2/U11Jj6nPpZqb7gyppMEkCQQCoGdVYDipU+hMMnvxa0zOIyQc/a+HE0lESqn+2ZPafYi9Z1RldRMvUXhP8U7s+OuhRwprdw2ivvOFrnWyz9lL2";
byte[] data = Base64.getDecoder().decode(privKeyStr);
/* Add PKCS#8 formatting */
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(0));
ASN1EncodableVector v2 = new ASN1EncodableVector();
v2.add(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()));
v2.add(DERNull.INSTANCE);
v.add(new DERSequence(v2));
v.add(new DEROctetString(data));
ASN1Sequence seq = new DERSequence(v);
byte[] privKey = seq.getEncoded("DER");
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privKey);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey key = fact.generatePrivate(spec);
Assert.assertNotNull("Failed to generate the private key", key);
}
user3719857
Updated on June 04, 2022Comments
-
user3719857 almost 2 years
I'm writing a program which takes as input from the console - the name of a zip file, name of a zip file to be made containig the (de/en)crypted files generated from the first zip and a file containing the public key. I get the exception when decrypting:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217) at java.security.KeyFactory.generatePrivate(KeyFactory.java:372) at com.Main.makePrivateKey(Main.java:148) at com.Main.decrypt(Main.java:40) at com.Main.main(Main.java:182) Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351) at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356) at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91) at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316) at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213) ... 4 more
Can't figure out why because the I use the rigth spec in the makePrivateKey method. The keys I'm testing with are(one line for a key each in a separate file):
Public key:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCE3pA746UfpC8sFk8ZJp0yupyJqj5jy6cjdxUYoP7mCm7c0mqQDeCcDNBYW2eSozCioPrH/9L+CDQEPLYakoem+jFnUKDH5+pru/0PJTJJF8Xh/ZT9eJlvsYBr1/qSfICf6RTs7kzwq9IuSZBw7/tfNEF9i0A8FVox6HOopXod1QIDAQAB
Private key:
MIICXQIBAAKBgQCE3pA746UfpC8sFk8ZJp0yupyJqj5jy6cjdxUYoP7mCm7c0mqQDeCcDNBYW2eSozCioPrH/9L+CDQEPLYakoem+jFnUKDH5+pru/0PJTJJF8Xh/ZT9eJlvsYBr1/qSfICf6RTs7kzwq9IuSZBw7/tfNEF9i0A8FVox6HOopXod1QIDAQABAoGANOFrYBqK5lvu1koOswDWQZFZqcSSzh8IZyoGwGWa7S0r0EECXlDXmuPSq8e9IfRG8ALHrH+ZlrbnFOSgyVSWHfpj3aH+qknoSX5TW2rMQHih8865xuqheMQ+RTZ7+BRDqNsYkzxB/Z8mqzpoJQSYf+H7nWxdDCgAJVYZzxl3DmUCQQD32iEjnwiwUjii8slcmvCEZl+z84DWNdvJOg6Z38sI4AvrfpKc1WAcDg1rNZCKrRgokh54wpLt08cpFcrD04c3AkEAiTzDmc0bdgfg5wj6xHFZpYlBwiGm/bjOR2PS57P0GNU5PsDllRbFqIuzArITutO5lvZZImzuYz7Lf+cQ73pxUwJBAOdEwmdaneDo17A0m2+to3/nhqWDMVSwLMU3RyiNigZeCMFU+bkd4PBMrHi9IoJDwacZsRU9eZwxYEUV8H2Jg0ECQEEkOqRSm2pXKwX/WSjNtQPCNxhy6NUeV6vDUmTxIjh3XYjP/ynZeVEbnoj1BjB0N2/U11Jj6nPpZqb7gyppMEkCQQCoGdVYDipU+hMMnvxa0zOIyQc/a+HE0lESqn+2ZPafYi9Z1RldRMvUXhP8U7s+OuhRwprdw2ivvOFrnWyz9lL2
The code for the program is bellow . Any help is wellcomed :)
package com; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.Enumeration; import java.util.Scanner; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import javax.crypto.Cipher; public class Main { public final static int BUFFER_SIZE = 117; public static void decrypt(String originalZipFileName, String newZipFileName, String privateKeyFileName) throws Exception { byte[] buffer = new byte[BUFFER_SIZE]; ZipFile originalZipFile = new ZipFile(originalZipFileName); ZipOutputStream newZipFile = new ZipOutputStream(new FileOutputStream(newZipFileName)); Enumeration<? extends ZipEntry> zipEntries = originalZipFile.entries(); String privateKey = getKeyString(privateKeyFileName); PrivateKey key = makePrivateKey(privateKey); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, key); File file = new File("temp.txt"); while(zipEntries.hasMoreElements()){ ZipEntry entry = zipEntries.nextElement(); ZipEntry copy = new ZipEntry(entry.getName()); newZipFile.putNextEntry(copy); int read; InputStream inputEntry = originalZipFile.getInputStream(entry); OutputStream outputFile = new FileOutputStream(file); while((read = inputEntry.read(buffer)) != -1){ outputFile.write(cipher.doFinal(buffer), 0, read); } InputStream inputTempFile = new FileInputStream(file); while((read = inputTempFile.read(buffer)) != -1){ newZipFile.write(buffer, 0, read); } newZipFile.closeEntry(); inputEntry.close(); inputTempFile.close(); outputFile.close(); file.delete(); } newZipFile.close(); } public static void encrypt(String originalZipFileName, String newZipFileName, String publicKeyFileName) throws Exception{ byte[] buffer = new byte[BUFFER_SIZE]; ZipFile originalZipFile = new ZipFile(originalZipFileName); ZipOutputStream newZipFile = new ZipOutputStream(new FileOutputStream(newZipFileName)); Enumeration<? extends ZipEntry> zipEntries = originalZipFile.entries(); String publicKey = getKeyString(publicKeyFileName); PublicKey key = makePublicKey(publicKey); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, key); File file = new File("temp.txt"); while(zipEntries.hasMoreElements()){ ZipEntry entry = zipEntries.nextElement(); ZipEntry copy = new ZipEntry(entry.getName()); newZipFile.putNextEntry(copy); int read; InputStream inputEntry = originalZipFile.getInputStream(entry); OutputStream outputFile = new FileOutputStream(file); while((read = inputEntry.read(buffer)) != -1){ outputFile.write(cipher.doFinal(buffer), 0, read); } InputStream inputTempFile = new FileInputStream(file); while((read = inputTempFile.read(buffer)) != -1){ newZipFile.write(buffer, 0, read); } newZipFile.closeEntry(); inputEntry.close(); inputTempFile.close(); outputFile.close(); file.delete(); } newZipFile.close(); } public static String getKeyString(String fileName){ String key = new String(); try { BufferedReader buf = new BufferedReader(new FileReader(fileName)); key = buf.readLine(); } catch ( IOException e) { e.printStackTrace(); } return key.trim(); } public static PublicKey makePublicKey(String stored) throws GeneralSecurityException { byte[] data = Base64.getDecoder().decode(stored); X509EncodedKeySpec spec = new X509EncodedKeySpec(data); KeyFactory fact = KeyFactory.getInstance("RSA"); return fact.generatePublic(spec); } public static PrivateKey makePrivateKey(String stored) throws GeneralSecurityException { byte[] data = Base64.getDecoder().decode(stored); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(data); KeyFactory fact = KeyFactory.getInstance("RSA"); return fact.generatePrivate(spec); } public static void main(String[] args) throws Exception { Scanner scan = new Scanner(System.in); System.out.println("Enter type of operation:"); String line = scan.nextLine(); if(line.equals("encrypt")){ System.out.println("Enter name of original ZIP file:"); String originalZipFileName = scan.nextLine(); System.out.println("Enter name of new ZIP file:"); String newZipFileName = scan.nextLine(); System.out.println("Enter name of file containg public key:"); String publicKeyFileName = scan.nextLine(); encrypt(originalZipFileName, newZipFileName, publicKeyFileName); } if(line.equals("decrypt")){ System.out.println("Enter name of original ZIP file:"); String originalZipFileName = scan.nextLine(); System.out.println("Enter name of new ZIP file:"); String newZipFileName = scan.nextLine(); System.out.println("Enter name of file containg private key:"); String privateKeyFileName = scan.nextLine(); decrypt(originalZipFileName, newZipFileName, privateKeyFileName); } } }