Duplicate :
|
|
Relates :
|
|
Relates :
|
jdk-14.0.2ADDITIONAL SYSTEM INFORMATION : Mac OS X 10.14.1 OpenJDK 11.0.1 Oracle JDK 1.8.0_192 A DESCRIPTION OF THE PROBLEM : A private key that has been saved to a PKCS12 keystore using custom PBE parameters in Java 8 (1.8.0_192) cannot be read in Java 11.0.1 and vice versa. It appears the ASN.1 encoding of the PBE parameters has incompatibly changed at some point between these two releases. REGRESSION : Last worked in version 8u192 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Create a PKCS#12 keystore in Java 8 and add a private key entry using a custom PBE scheme: KeyStore.PrivateKeyEntry privateKeyEntry = new PrivateKeyEntry(keyPair.getPrivate(), new Certificate[] { cert }); keyStore.setEntry("server", privateKeyEntry, new PasswordProtection("password".toCharArray(), "PBEWithHmacSHA512AndAES_256", new PBEParameterSpec(salt, 100_000))); Save the PKCS12 keystore to a file. Now try to load the same keystore and key from Java 11. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - The key is loaded correctly without error. ACTUAL - Exception in thread "main" java.security.UnrecoverableKeyException: Private key not stored as PKCS#8 EncryptedPrivateKeyInfo: java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 42) at java.base/sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:373) at java.base/sun.security.util.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:90) at java.base/java.security.KeyStore.getKey(KeyStore.java:1057) at PemTest.main(PemTest.java:72) Caused by: java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 42) at java.base/sun.security.util.ObjectIdentifier.<init>(ObjectIdentifier.java:257) at java.base/sun.security.util.DerInputStream.getOID(DerInputStream.java:320) at java.base/com.sun.crypto.provider.PBES2Parameters.parseKDF(PBES2Parameters.java:282) at java.base/com.sun.crypto.provider.PBES2Parameters.engineInit(PBES2Parameters.java:267) at java.base/java.security.AlgorithmParameters.init(AlgorithmParameters.java:312) at java.base/sun.security.x509.AlgorithmId.decodeParams(AlgorithmId.java:132) at java.base/sun.security.x509.AlgorithmId.<init>(AlgorithmId.java:114) at java.base/sun.security.x509.AlgorithmId.parse(AlgorithmId.java:374) at java.base/sun.security.pkcs.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:80) at java.base/sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:362) ... 3 more ---------- BEGIN SOURCE ---------- import java.io.FileInputStream; import java.io.FileOutputStream; import java.math.BigInteger; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStore.PasswordProtection; import java.security.KeyStore.PrivateKeyEntry; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Date; import java.util.concurrent.TimeUnit; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; public class Pkcs12Test { public static void main(String[] args) throws Exception { // *** RUN THIS AS JAVA 8 *** KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); keyPairGenerator.initialize(256); KeyPair keyPair = keyPairGenerator.generateKeyPair(); SecureRandom secureRandom = SecureRandom.getInstanceStrong(); BigInteger serial = new BigInteger(159, secureRandom); X500Name self = new X500Name("cn=localhost"); X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(self, serial, new Date(), new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3650)), self, keyPair.getPublic()); X509CertificateHolder certHolder = certificateBuilder.build(new JcaContentSignerBuilder("SHA256WithECDSA") .setSecureRandom(secureRandom) .build(keyPair.getPrivate())); X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certHolder); KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null, null); byte[] salt = new byte[20]; new SecureRandom().nextBytes(salt); KeyStore.PrivateKeyEntry privateKeyEntry = new PrivateKeyEntry(keyPair.getPrivate(), new Certificate[] { cert }); keyStore.setEntry("server", privateKeyEntry, new PasswordProtection("password".toCharArray(), "PBEWithHmacSHA512AndAES_256", new PBEParameterSpec(salt, 100_000))); keyStore.store(new FileOutputStream("/tmp/keystore.p12"), "changeit".toCharArray()); /*** RUN THIS AS JAVA 11 ***/ keyStore.load(new FileInputStream("/tmp/keystore.p12"), "changeit".toCharArray()); Key key = keyStore.getKey("server", "password".toCharArray()); System.out.println("Reloaded key: " + key); } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : Either do not use a custom PBE encryption scheme or recreate keystores from scratch when moving to Java 11. FREQUENCY : always
|