如何在SunPKCS11中获取会话句柄

时间:2014-01-18 08:10:53

标签: java security hsm

我正在使用SoftHSM,并且能够在令牌中生成和存储密钥。为了使用SunPKCS接口,许多方法都需要会话句柄,我对如何检索它们感到茫然。 目前我正在使用SoftHSM和PKCS11如下。注释中的代码是我尝试使用SUNPKCS11接口签名的代码。 任何关于如何包装和解包密钥的示例代码也将非常感激。我正在尝试使用PKCS11从一个令牌备份密钥到另一个令牌,如果我的理解是正确的,那么方法必须是通过包装.... Sitaraman

public static void main(String[] args) {
    // TODO code application logic hereString configName = "softhsm.cfg";
    try {
        // Set up the Sun PKCS 11 provider

        String configName = "/etc/softhsm.cfg";
        Provider p = new SunPKCS11(configName);

        String configName1 = "/etc/softhsm1.cfg";
        Provider p1 = new SunPKCS11(configName1);

        if (-1 == Security.addProvider(p)) {
            throw new RuntimeException("could not add security provider");
        }
        PKCS11 p11 = PKCS11.getInstance("/usr/local/lib/softhsm/libsofthsm.so", "C_GetFunctionList", null, false);

       /* p11.C_GetSessionInfo(0);
        CK_INFO cki = p11.C_GetInfo();

        long[] slots = p11.C_GetSlotList(true);
        String label = new String(p11.C_GetTokenInfo(slots[0]).label);
        Object obj = new Object();
        long sessionhandle = p11.C_OpenSession(slots[0], 1, null, null);

        CK_MECHANISM ckm = new CK_MECHANISM();
        ckm.mechanism       = PKCS11Constants.CKM_RSA_PKCS;
        CK_ATTRIBUTE[] cka = new CK_ATTRIBUTE[1];   
        CK_ATTRIBUTE[] cka1 = new CK_ATTRIBUTE[1];           
        long[] keypair =p11.C_GenerateKeyPair(slots[1], ckm, cka, cka1);
        */
        //System.out.println("No. of slots" + slots.length + "label" + label);
        // Load the key store
        char[] pin = "vit12345".toCharArray();
        char[] pin1 = "User12345".toCharArray();
        KeyStore ks = KeyStore.getInstance("PKCS11", p);
        KeyStore ks1 = KeyStore.getInstance("PKCS11", p1);
        ks.load(null, pin);
        ks1.load(null, pin1);
        Entry e;
        KeyStore.PrivateKeyEntry e1;

        // Generate the key
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", p);
        keyGen.initialize(1024, sr);
        KeyPair keyPair = keyGen.generateKeyPair();
        PrivateKey pk = keyPair.getPrivate();

        // Java API requires a certificate chain
        X509Certificate[] chain = generateV3Certificate(keyPair);

        ks.setKeyEntry("ALIAS-GOES-HERE", pk, "1234".toCharArray(), chain);
        //ks1.setKeyEntry("ALIAS-GOES-HERE1", pk, "1234".toCharArray(), chain);
        ks.store(null);
        //ks1.store(null);
        Key k = ks.getKey("ALIAS-GOES-HERE", "1234".toCharArray());
        System.out.println("key string is " + k.toString());
        PrivateKey pk1 = (PrivateKey) k;

        System.out.println("OK");
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:2)

您可以像使用示例代码中的注释块一样使用SunPKCS11包装器中的方法。

您可以通过以下示例代码获取会话句柄:

CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
PKCS11 p11 = PKCS11.getInstance("D:\\cryptoki.dll", "C_GetFunctionList", initArgs, false);
long hSession = p11.C_OpenSession(0, CKF_SERIAL_SESSION| CKF_RW_SESSION, null, null);
char [] pin = {'1', '2', '3', '4', '5', '6', '7', '8'};
p11.C_Login(hSession, CKU_USER, pin);
// do work
p11.C_Logout(hSession);
p11.C_CloseSession(hSession);

例如,要生成AES密钥并获取生成密钥的句柄,请使用以下(作为示例):

        CK_ATTRIBUTE[] aesKeyObject = new CK_ATTRIBUTE[13];

        try
        {
            aesKeyObject[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
            aesKeyObject[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_AES);
            aesKeyObject[2] = new CK_ATTRIBUTE(CKA_VALUE_LEN, 32);
            aesKeyObject[3] = new CK_ATTRIBUTE(CKA_TOKEN, true);
            aesKeyObject[4] = new CK_ATTRIBUTE(CKA_LABEL, label);
            aesKeyObject[5] = new CK_ATTRIBUTE(CKA_PRIVATE, true);
            aesKeyObject[6] = new CK_ATTRIBUTE(CKA_EXTRACTABLE, false);
            aesKeyObject[7] = new CK_ATTRIBUTE(CKA_WRAP, true);
            aesKeyObject[8] = new CK_ATTRIBUTE(CKA_UNWRAP, true);
            aesKeyObject[9] = new CK_ATTRIBUTE(CKA_ENCRYPT, true);
            aesKeyObject[10] = new CK_ATTRIBUTE(CKA_DECRYPT, true);
            aesKeyObject[11] = new CK_ATTRIBUTE(CKA_TRUSTED, true);
            aesKeyObject[12] = new CK_ATTRIBUTE(CKA_ID, 1550);

            CK_MECHANISM mech = new CK_MECHANISM(CKM_AES_KEY_GEN);

            long newAESKeyHandle = p11.C_GenerateKey(hSession, mech, aesKeyObject);     
        }catch(Exception e)
        {
        }

然后您可以使用此句柄来使用新生成的密钥。 此外,PKCS11包装器具有包装和解包密钥的方法,您可以使用这些方法进行备份:

public native byte[] C_WrapKey(long hSession,
    CK_MECHANISM pMechanism,
    long hWrappingKey,
    long hKey) throws PKCS11Exception

public native long C_UnwrapKey(long hSession,
    CK_MECHANISM pMechanism,
    long hUnwrappingKey,
    byte[] pWrappedKey,
    CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception