Why can EncryptedPrivateKeyInfo not read my PKCS#8 encrypted private key in Java?
Asked Answered
E

1

3

I'm trying to decrypt a password-encrypted private key in Java, and I've come across this previous question, but when I try the same, I get the following exception:

Exception in thread "main" java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 48)
at sun.security.util.ObjectIdentifier.<init>(ObjectIdentifier.java:257)
at sun.security.util.DerInputStream.getOID(DerInputStream.java:314)
at com.sun.crypto.provider.PBES2Parameters.engineInit(PBES2Parameters.java:267)
at java.security.AlgorithmParameters.init(AlgorithmParameters.java:293)
at sun.security.x509.AlgorithmId.decodeParams(AlgorithmId.java:132)
at sun.security.x509.AlgorithmId.<init>(AlgorithmId.java:114)
at sun.security.x509.AlgorithmId.parse(AlgorithmId.java:372)
at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:95)
at TestDecryptKey.main(TestDecryptKey.java:65)

where TestDecryptKey.java is my test file. Here's a snippet of what I'm doing:

import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.spec.PBEKeySpec;
import java.util.Base64;
import java.security.GeneralSecurityException;
import java.io.IOException;

public class TestDecryptKey {
  public static void main(String[] args) throws GeneralSecurityException, IOException {
    String encryptedBase64PrivateKey = "MII...";
    String password = "...";
    byte[] encryptedPrivateKey = Base64.getDecoder().decode(encryptedBase64PrivateKey.getBytes("UTF-8"));
    PBEKeySpec pbeSpec = new PBEKeySpec(password.toCharArray());
    // Exception is thrown here
    EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey);
 }
}

I'm assuming it's claiming that the encrypted key data I've provided isn't a valid encrypted key, but openssl disagrees. I saved the Base64 string with the header and footer "-----BEGIN ENCRYPTED PRIVATE KEY-----" and "-----END ENCRYPTED PRIVATE KEY-----" as the file "pem_key" and using the following command and the password from above:

openssl pkcs8 -inform pem -in pem_key -outform der

I'm able to output the decrypted key bytes. Where am I going wrong?

Ecology answered 16/8, 2018 at 18:31 Comment(3)
It's clear that snippet cannot represent what's going on, because it doesn't compile. Please create a valid minimal, complete, and verifiable example. Compile and run it yourself and make sure it works before posting it. You can create a test private key that you only use for this example, and post that.Harmon
JCE parsing of PBES2Parameters is buggy. If you have or get BouncyCastle it works correctly for this, and is covered by existing Qs e.g. #46767781 . Alternatively, Suncle will work if you create or re-create your PKCS8 to use a NON-PBES2 scheme: PKCS5-PBES1 schemes are mostly weak, but PKCS12-PBE are mostly okay. Or you could write the ASN.1 parsing yourself, but that's not easy.Cryogen
Edited to make the example compile-able. @dave_thompson_085, I think that might be the case because I've tried re-encrypting the key with the passphrase after I decrypted it using openssl and then provided that new encrypted key to the EncryptePrivateKeyInfo which works.Ecology
H
1

I've got the same error when tying to use a keystore generated with x64 JDK's keytool for java app run with x32 JVM. Changing JVM to x64 helped.

Humfried answered 8/4, 2022 at 5:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.