JDK-8348732 : SunJCE and SunPKCS11 have different PBE key encodings
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.crypto:pkcs11
  • Affected Version: 21
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2025-01-27
  • Updated: 2025-05-14
  • Resolved: 2025-05-01
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 25
25 b22Fixed
Related Reports
CSR :  
Causes :  
Causes :  
Duplicate :  
Relates :  
Sub Tasks
JDK-8356198 :  
JDK-8356217 :  
JDK-8356312 :  
Description
There is an inconsistency between SunJCE and SunPKCS11 on "PBEWith***" SecretKeyFactory. SunJCE simply generates a secret key with the password encoded in bytes (and let the cipher do the key derivation later) but SunPKCS11 derives the key in the factory.

For example, the "PBEWithHmacSHA1AndAES_256" factory generates different keys from `new PBEKeySpec("12345".toCharArray(), new byte[8], 100)`:

PBEWithHmacSHA1AndAES_256 RAW 31:32:33:34:35
PBEWithHmacSHA1AndAES_256 RAW 75:38:b0:e2:b2:93:0b:36:2a:bf:2a:d8:3a:e0:34:85:c5:9e:41:06:7c:36:d2:b1:ce:e1:8b:9a:c1:3c:62:fa

Note that the generated keys have the same algorithm and format, only the bytes are different.

On the other hand, for "PBKDF2***" factories, both generate derived keys.
Comments
Changeset: 6536430a Branch: master Author: Valerie Peng <valeriep@openjdk.org> Date: 2025-05-01 23:08:16 +0000 URL: https://git.openjdk.org/jdk/commit/6536430a3bdedcf5e0636e0eb27bde5e0d7b40fd
01-05-2025

[~valeriep] I agree that SunJCE PBE Cipher impls have set a precedence, and removing the ASCII check from com.sun.crypto.provider.PBEKey would certainly help. I found some issues when dealing with non-ASCII passwords in the proposed PR, please see my review suggestions.
18-03-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/24068 Date: 2025-03-14 21:58:47 +0000
14-03-2025

[~fferrari] [~mbalao] The way I view it is that the key derivation should be handled inside the PBE Cipher and PBE Mac impls. Given how long the SecretKeyFactory for PBE Cipher impls have been around for SunJCE provider, it can be quite confusing for SunPKCS11 provider to provide the same named SecretKeyFactory returning key encoding containing the derived bytes instead of the password. Is the main reason for this is to support non-ASCII PBE passwords? Maybe it's time to remove the ASCII check inside com.sun.crypto.provider.PBEKey class? Would it help?
12-03-2025

CC: [~mbalao] Hi, I would like to note that we were aware of this during the development of JDK-8301553, and that the difference in behavior was intentional. However, we made sure to test interoperability between SunPKCS11 and SunJCE: you should be able to use the key generated by one provider's SecretKeyFactory on the other provider's Cipher/Mac. It didn't make sense to us for P11SecretKeyFactory to return a P11SecretKey with the password bytes. We would be creating that key inside the PKCS #11 token, just to hold the data and never use the key object, since the PKCS #11 API to derive the actual key doesn't accept a key, but a buffer with the encoded password (see https://github.com/openjdk/jdk/blob/jdk-25+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java#L402-L441). On the other hand, it also seemed weird for P11SecretKeyFactory to generate a com.sun.crypto.provider.PBEKey (P11SecretKeyFactory always generates keys whose type inherits from P11SecretKeyKey). In addition, this allowed SunPKCS11 versions of the algorithms to support non-ASCII PBE passwords, as com.sun.crypto.provider.PBEKey is too restrictive about that.
06-02-2025

SunJCE provider 1) returns com.sun.crypto.provider.PBEKey objects for PBEWithHmacSHAxxxAndAES_yyyy SecretKeyFactory impls. This PBEKey class implements javax.crypto.SecretKey and returns the password bytes as the key encoding. Note that the com.sun.crypto.provider.PBEKey class does NOT implement the javax.crypto.interfaces.PBEKey. 2) returns com.sun.crypto.provider.PBKDF2KeyImpl objects for PBKDF2WithHmacSHAXXX SecretKeyFactory impls. This PBKDF2KeyImpl class implements javax.crypto.interfaces.PBEKey and returns the derived bytes as the key encoding and the password (char[]). salt (byte[]). and iteration count (int) for the getter methods defined under javax.crypto.interfaces.PBEKey. When adding the PBE support to PKCS11 provider (see JDK-8301553), its PBE and PBKDF2 SecretKeyFactory impl both returns key objects implement the javax.crypto.interfaces.PBEKey and return the derived bytes as the key encoding. This matches com.sun.crypto.provider.PBKDF2KeyImpl class but is inconsistent with the com.sun.crypto.provider.PBEKey class.
28-01-2025

If this is resolved and both start using the same encoding, it is worth documenting this in the Java Security Standard Algorithm Names Specification.
27-01-2025