-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
26
-
None
https://datatracker.ietf.org/doc/html/rfc8018#section-7.1.1 describes the parameters for PBMAC1 including S (salt), c (iteration counts, or ic), and dkLen (key length). However, in the Java implementation in PBMAC1Core.java, key length is hardcoded to block length of the message digest algorithm and the user cannot change it. See https://github.com/openjdk/jdk/blob/1472124489c841642996ae984e21c533ffec8091/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java#L176.
In order to specify a different key length, users have to derive the key first with
var skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
var pbeKey = skf.generateSecret(new PBEKeySpec(passwd, salt, ic, dkLen));
But then, this key cannot be used in a PBEWithHmacSHA256 Mac because only the password/salt/ic inside will be used and the generated key is actually abandoned and key length is forgotten! See https://github.com/openjdk/jdk/blob/1472124489c841642996ae984e21c533ffec8091/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java#L110-L115.
var m = Mac.getInstance("PBEWithHmacSHA256");
m.init(pbeKey); // dkLen is forgotten, 64 is used
The workaround is to use the derived key in a raw (!) Mac, like this:
var m2 = Mac.getInstance("HmacSHA256");
m2.init(pbeKey); // pbeKey.getEncoded() is used, which has dkLen bits
This makes the PBE Mac useless when an arbitrary key length is needed. For example, in https://datatracker.ietf.org/doc/html/rfc9579#name-recommended-parameters:
The length of the key generated by the used KDF MUST be encoded explicitly in the parameters field and SHOULD be the same size as the HMAC function output size.
We should either enhance the PBE Mac to accept a password (as a SecretKey) directly with salt/ic/key length configurable. Or, after the PBKDF2 SecretKeyFactory generates the key it can be used in the PBC Mac without losing the key length info.
In order to specify a different key length, users have to derive the key first with
var skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
var pbeKey = skf.generateSecret(new PBEKeySpec(passwd, salt, ic, dkLen));
But then, this key cannot be used in a PBEWithHmacSHA256 Mac because only the password/salt/ic inside will be used and the generated key is actually abandoned and key length is forgotten! See https://github.com/openjdk/jdk/blob/1472124489c841642996ae984e21c533ffec8091/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java#L110-L115.
var m = Mac.getInstance("PBEWithHmacSHA256");
m.init(pbeKey); // dkLen is forgotten, 64 is used
The workaround is to use the derived key in a raw (!) Mac, like this:
var m2 = Mac.getInstance("HmacSHA256");
m2.init(pbeKey); // pbeKey.getEncoded() is used, which has dkLen bits
This makes the PBE Mac useless when an arbitrary key length is needed. For example, in https://datatracker.ietf.org/doc/html/rfc9579#name-recommended-parameters:
The length of the key generated by the used KDF MUST be encoded explicitly in the parameters field and SHOULD be the same size as the HMAC function output size.
We should either enhance the PBE Mac to accept a password (as a SecretKey) directly with salt/ic/key length configurable. Or, after the PBKDF2 SecretKeyFactory generates the key it can be used in the PBC Mac without losing the key length info.