-
Bug
-
Resolution: Fixed
-
P2
-
7, 8, 11, 12
-
b23
-
x86_64
-
os_x
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8214836 | 11.0.3-oracle | Ivan Gerasimov | P2 | Closed | Fixed | master |
JDK-8219431 | 11.0.3 | Weijun Wang | P2 | Resolved | Fixed | master |
JDK-8268479 | openjdk8u312 | Alexey Bakhtin | P2 | Resolved | Fixed | b01 |
JDK-8264689 | 8u301 | Sean Coffey | P2 | Closed | Fixed | b03 |
JDK-8266278 | 7u321 | Prasadarao Koppula | P2 | Resolved | Fixed | b01 |
JDK-8264692 | 7u311 | Prasadarao Koppula | P2 | Closed | Fixed | b04 |
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
- backported by
-
JDK-8219431 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Resolved
-
JDK-8266278 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Resolved
-
JDK-8268479 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Resolved
-
JDK-8214836 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Closed
-
JDK-8264689 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Closed
-
JDK-8264692 A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
- Closed
- duplicates
-
JDK-8220734 java.security.KeyStore should support PKCS#12 files with AES
- Closed
- relates to
-
JDK-8202837 PBES2 AlgorithmId encoding error in PKCS12 KeyStore
- Closed
-
JDK-8153005 Upgrade the default PKCS12 encryption/MAC algorithms
- Resolved