I am trying to configure Java to run in FIPS mode. I am running openjdk 1.8.0 and NSS 3.79.0 on an AmazonLinux2 AWS instance. As per whatever documentation I could find, I configured the java.security file (security providers and keystore.type only):
security.provider.1=sun.security.pkcs11.SunPKCS11 /opt/fipsconfig/pkcs11.cfg
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSSFIPS
and
keystore.type=PKCS11
Next, I configured the /opt/fipsconfig/pkcs11.cfg token to be:
[root@ip-10-4-93-132 hmac-test]# cat /opt/fipsconfig/pkcs11.cfg
name = NSSFIPS
nssLibraryDirectory = /usr/lib64
nssSecmodDirectory = /etc/pki/nssdb
nssModule = fips
nssDbMode = readOnly
I then verified that /etc/pki/nssdb is FIPS enabled:
modutil -chkfips true -dbdir /etc/pki/nssdb
FIPS mode enabled.
And the token looks good:
modutil -dbdir /etc/pki/nssdb -list
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.79
slots: 1 slot attached
status: loaded
slot: NSS FIPS 140-2 User Private Key Services
token: NSS FIPS 140-2 Certificate DB
uri: pkcs11:token=NSS%20FIPS%20140-2%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
Using this demo:
[root@ip-10-4-93-132 hmac-test]# cat hmac.java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.KeyStore;
public class hmac {
public static String encode(String algorithm, String key, String data) throws Exception {
KeyStore ks = KeyStore.getInstance("PKCS11");
if (ks == null) System.out.println("ks is null");
else {
ks.load(null, null);
System.out.println("keystore PKCS11 type = " + ks.getDefaultType());
System.out.println("keystore PKCS11 provider = " + ks.getProvider());
System.out.println("keystore PKCS11 size = " + ks.size());
}
Mac sha256_HMAC = Mac.getInstance(algorithm);
//System.out.println("HMAC Provider: " + sha256_HMAC.getProvider());
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
sha256_HMAC.init(secret_key);
byte[] bytes = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder result = new StringBuilder();
for (byte aByte : bytes) {
result.append(String.format("%02x", aByte));
}
return result.toString();
}
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("Invalid Usage.\nUsage: java hmac <algorithm> <key> <data>");
System.exit(-1);
}
System.out.println(encode(args[0], args[1], args[2]));
}
}
produces this error when run with the following options:
java hmac HmacSHA256 "key" "The quick brown fox jumps over the lazy dog"
keystore PKCS11 type = PKCS11
keystore PKCS11 provider = SunPKCS11-NSSFIPS version 1.8
keystore PKCS11 size = 2
Exception in thread "main" java.security.InvalidKeyException: Could not create key
at sun.security.pkcs11.P11SecretKeyFactory.createKey(P11SecretKeyFactory.java:274)
at sun.security.pkcs11.P11SecretKeyFactory.convertKey(P11SecretKeyFactory.java:179)
at sun.security.pkcs11.P11SecretKeyFactory.convertKey(P11SecretKeyFactory.java:111)
at sun.security.pkcs11.P11Mac.engineInit(P11Mac.java:204)
at javax.crypto.Mac.chooseProvider(Mac.java:350)
at javax.crypto.Mac.init(Mac.java:415)
at hmac.encode(hmac.java:19)
at hmac.main(hmac.java:34)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_VALUE_INVALID
at sun.security.pkcs11.wrapper.PKCS11.C_CreateObject(Native Method)
at sun.security.pkcs11.P11SecretKeyFactory.createKey(P11SecretKeyFactory.java:269)
... 7 more
If I run the demo in full java debug mode, with:
java -Djava.security.debug=all hmac HmacSHA256 key "The quick brown fox jumps over the lazy dog" > OUT 2>&1
The output looks reasonable, except for the exception produced at the very end.
I've looked all over the internet for a hint on what is going wrong, but I just can't seem to find anything. I took a look at the P11SecretKeyFactory.java code, and I believe the initial exception thrown is of type PKCS11Exception (where it then prints the "Could not create key" and then throws the new InvalidKeyException).
In the createKey() function, I see 3 attributes are being set:
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
I am wondering if one of these attributes (probably the last 2) could be producing the CKR_ATTRIBUTE_VALUE_INVALID error?
Has anyone run across this and if so would you be able to provide a clue as to what is wrong?
Thank you.