user3240160
user3240160

Reputation: 79

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DER input, Integer tag error

Here's the exception:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DER input, Integer tag error
  at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
  at java.security.KeyFactory.generatePrivate(Unknown Source)

Caused by: java.security.InvalidKeyException: IOException : DER input, Integer tag error at sun.security.pkcs.PKCS8Key.decode(Unknown Source)

Here's the code:

import java.io.*;
import java.security.*;
import java.security.KeyStore.PasswordProtection;
import java.security.cert.CertificateException;
import java.security.spec.*;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;

import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.util.encoders.Base64;

public class KeyPairUtil {

final static String keyStoreFile = "D:\\aeskey.jks";

private static final ASN1ObjectIdentifier AES = ASN1ObjectIdentifier.getInstance(NISTObjectIdentifiers.id_aes128_CBC);

public static void main(String[] args) throws Exception {

    final java.security.KeyPairGenerator gen = java.security.KeyPairGenerator.getInstance("RSA");
    gen.initialize(1024);
    final KeyPair keyPair = gen.generateKeyPair();
    wrapKeypairWithSymmetricKey(keyPair);
}

public static KeyPair wrapKeypairWithSymmetricKey(KeyPair keyPair) {

    try {
        PrivateKey priv = keyPair.getPrivate();
        SecretKey symmetricKey = getSymmetricKeyFromJKSFile();
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
        cipher.init(Cipher.WRAP_MODE, symmetricKey, iv);
        System.out.println(iv.getIV());
        ASN1Encodable params = new DEROctetString(iv.getIV());
        AlgorithmIdentifier algId = new AlgorithmIdentifier(AES, params);
        byte[] wrappedKey = cipher.wrap(priv);
        KeyFactory keyFactory = KeyFactory.getInstance(priv.getAlgorithm());
        byte[] pkcs8enc = new EncryptedPrivateKeyInfo(algId, wrappedKey).getEncoded();
        EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8enc);
        PrivateKey privateKey2 = keyFactory.generatePrivate(privateKeySpec); //throwing error in this line
        KeyPair keypair = new KeyPair(keyPair.getPublic(), privateKey2);
        return keypair;
    } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException | IllegalBlockSizeException | IOException | InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return null;
}

private static SecretKey getSymmetricKeyFromJKSFile() {

    String jkspassword = "password";
    PasswordProtection keyPassword = new PasswordProtection("keypassword".toCharArray());
    try {
        KeyStore keyStore = loadKeyStore(keyStoreFile, jkspassword);
        // retrieve the stored key back
        KeyStore.Entry entry = keyStore.getEntry("keyentry", keyPassword);
        SecretKey keyFound = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
        return keyFound;
    } catch (CertificateException | IOException | NoSuchAlgorithmException | UnrecoverableEntryException | KeyStoreException e) {
        e.printStackTrace();
    }
    return null;
}

private static KeyStore loadKeyStore(String fileName, String jkspassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {

    File file = new File(fileName);
    final KeyStore keyStore = KeyStore.getInstance("JCEKS");
    if (file.exists()) {
        keyStore.load(new FileInputStream(file), jkspassword.toCharArray());
    }
    return keyStore;
}
}

I hope somebody knows how to solve?

Upvotes: 6

Views: 25503

Answers (2)

I ran into a similar issue with a Java application I work with. Turns out that the private key (in PEM format) was not formatted correctly.

Check out this post from comodo to verify if the private key works and matches the public key.

Upvotes: 2

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

I'll assume that you want to generate a wrapped PKCS#8 private key.

PKCS#8 however has both an inner and external DER encoded structure around it. The inner structure is to identify the stored key, i.e. it will indicate an RSA private key. This is what's being wrapped. The outer structure will indicate how the private key was wrapped. This is what is currently missing.

So what's happening is that the parser doesn't find the outer structure simply because you haven't generated it. The structure is (partly) defined in the EncryptedPrivateKeyInfo documentation, and I assume you can use the constructor to generate it.

Upvotes: 3

Related Questions