JDK-8149411 : PKCS12KeyStore cannot extract AES Secret Keys
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u66,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-02-08
  • Updated: 2017-12-21
  • Resolved: 2016-02-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9 Other
7u171Fixed 8u102Fixed 9 b107Fixed openjdk7uFixed
Related Reports
Relates :  
Description
A PKCS12 KeyStore cannot decrypt and extract an encoded AES SecretKey. The attached program fails with:

Exception in thread "main" java.security.UnrecoverableKeyException: Get Key failed: AES SecretKeyFactory not available
	at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:419)
	at sun.security.pkcs12.PKCS12KeyStore.engineGetEntry(PKCS12KeyStore.java:1291)
	at sun.security.util.KeyStoreDelegator.engineGetEntry(KeyStoreDelegator.java:166)
	at java.security.KeyStore.getEntry(KeyStore.java:1535)
	at P12SecretKey.run(P12SecretKey.java:47)
	at P12SecretKey.main(P12SecretKey.java:21)
Caused by: java.security.NoSuchAlgorithmException: AES SecretKeyFactory not available
	at javax.crypto.SecretKeyFactory.<init>(SecretKeyFactory.java:122)
	at javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:160)
	at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:396)
	... 5 more

The problem is that the PKCS12 KeyStore uses a SecretKeyFactory to decode AES keys, but there is no AES SecretKeyFactory implementation except on Solaris (via the PKCS11 provider). It turns out that for SecretKeyFactory, AES is not an essential requirement, since you can use a generic SecretKeySpec object to create an AES key and don't really need a SecretKeyFactory. Also, in general a SecretKeyFactory should not be used with a SecretKeySpec, since by definition, SecretKeySpec objects contain the raw key in a provider-independent format and do not need to be decoded. 
Comments
The following patch fixed the issue for me: --- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Mon Feb 08 10:46:42 2016 -0800 +++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Tue Feb 09 07:10:18 2016 -0500 @@ -394,19 +394,19 @@ // decode secret key } else { - SecretKeyFactory sKeyFactory = - SecretKeyFactory.getInstance(keyAlgo); byte[] keyBytes = in.getOctetString(); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, keyAlgo); // Special handling required for PBE: needs a PBEKeySpec if (keyAlgo.startsWith("PBE")) { + SecretKeyFactory sKeyFactory = + SecretKeyFactory.getInstance(keyAlgo); KeySpec pbeKeySpec = sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class); key = sKeyFactory.generateSecret(pbeKeySpec); } else { - key = sKeyFactory.generateSecret(secretKeySpec); + key = secretKeySpec; } if (debug != null) {
09-02-2016