Search code examples
javapkcs#11hardware-security-modulecryptoki

Pkcs#11 with Luna Cloud HSM: private key listed with cmu list is not found in Java KeyStore


Connecting to Luna Cloud HSM I am able to add a RSA private key to the HSM (either by cmu importkey or by cmu gen) and the command-line tool cmu list displays this key from the server.

I am connecting to the HSM using Pkcs#11 with minimal configuration file

name=LunaHsm
description=SunPKCS11 accessing LunaHsm
library=libCryptoki2.so
showInfo=true
slot=3

But I cannot find the private key as I was expecting. I enabled logging for java.security.debug=sunpkcs11 (log bellow) and the Java code is correctly initializing the PKCS#11 library, listing the correct information for the provider SunPKCS11-LunaHsm, it finds the correct slot but it only finds the secret keys present on this slot, without the private key I was expecting to find. I'm using OpenJdk 11.0.18

SunPKCS11 loading lunahsm-pkcs11.cfg
sunpkcs11: Initializing PKCS#11 library libCryptoki2.so
Information for provider SunPKCS11-LunaHsm
Library info:
  cryptokiVersion: 2.20
  manufacturerID: SafeNet                         
  flags: 0
  libraryDescription: Chrystoki                       
  libraryVersion: 10.07
All slots: 0, 1, 2, 3
Slots with tokens: 3
Slot info for slot 3:
  slotDescription: Net Token Slot                                                  
  manufacturerID: SafeNet                         
  flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
  hardwareVersion: 0.00
  firmwareVersion: 0.00
Token info for token in slot 3:
  label: my_partition          
  manufacturerID: SafeNet                         
  model: Cryptovisor7    
  serialNumber: 123123   
  flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_RESTORE_KEY_NOT_NEEDED | CKF_TOKEN_INITIALIZED
  ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
  ulSessionCount: 1
  ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
  ulRwSessionCount: 1
  ulMaxPinLen: 255
  ulMinPinLen: 7
  ulTotalPublicMemory: 159744
  ulFreePublicMemory: 156528
  ulTotalPrivateMemory: 159744
  ulFreePrivateMemory: 156528
  hardwareVersion: 0.00
  firmwareVersion: 7.03
  utcTime: 20241008132333  
<list of Mechanisms>
sunpkcs11: login succeeded

If I use the Luna JSP LunaProvider.jar then I can find also the private keys:

Security.addProvider(new LunaProvider());
myStore = KeyStore.getInstance("Luna");
ByteArrayInputStream is1 = new ByteArrayInputStream(
                ("slot:" + slot + "\ncaching:false" + "\ndefertokenization:true").getBytes());
myStore.load(is1, passwd.toCharArray());

But I want to only use the Pkcs#11 API:

Provider provider = Security.getProvider("SunPKCS11");
provider = provider.configure("path/to/config/file");
KeyStore ks = KeyStore.getInstance("PKCS11", provider);
ks.load(is1,passwd.toCharArray());

Any suggestion?


Solution

  • I just tested SunPKCS11 with Luna HSM. Here's how it worked for me.

    sampaul@jaguarkick:~$ openssl rand -hex 8
    df019547a558d541
    
    sampaul@jaguarkick:~$ cmu gen -sign 1 -verify 1 -encrypt 1 -decrypt 1 -publicexponent 65537 -modulusBits 2048 -keytype rsa -id=df019547a558d541
    
    sampaul@jaguarkick:~$ cmu self -id=df019547a558d541 -label=signing_key
    
    sampaul@jaguarkick:~$ java SunPKCS11Test.java config.cfg userpinco signing_key
    

    SunPKCS11 Configuration:

    sampaul@jaguarkick:~$ cat config.cfg
    name = Luna
    library = /usr/safenet/lunaclient/lib/libcklog2.so
    slot = 0
    

    SunPKCS11Test.java:

    import java.security.*;
    import java.security.KeyStore.*;
    import javax.crypto.spec.*;
    
    public class SunPKCS11Test {
            private static String fileName = null;
            private static String slotPin = null;
            private static String keyAlias = null;
            private static final String RAW_DATA = "Earth is the third planet of our Solar System.";
            private static byte[] signature = null;
            private static final String PROVIDER = "SunPKCS11-Luna";
            private static KeyStore keyStore = null;
            private static PrivateKeyEntry prKe = null;
    
            private static void addSunPKCS11() {
                    Provider prod = Security.getProvider("SunPKCS11");
                    prod = prod.configure(fileName);
                    Security.insertProviderAt(prod, 5);
            }
    
            private static void loadKeyStore() throws Exception {
                    keyStore = KeyStore.getInstance("PKCS11", PROVIDER);
                    keyStore.load(null, slotPin.toCharArray());
            }
    
            private static void signData() throws Exception {
                    Signature sign = Signature.getInstance("sha256WithRSA", PROVIDER);
                    sign.initSign(prKe.getPrivateKey());
                    sign.update(RAW_DATA.getBytes());
                    signature = sign.sign();
            }
    
            private static void loadSigningKeys() throws Exception {
                    prKe = (PrivateKeyEntry)keyStore.getEntry(keyAlias, new PasswordProtection("abcd".toCharArray()));
            }
    
            public static void main(String args[]) throws Exception {
                    fileName = args[0];
                    slotPin = args[1];
                    keyAlias = args[2];
                    addSunPKCS11();
                    loadKeyStore();
                    loadSigningKeys();
                    signData();
            }
    }
    

    Hope this helps!