java - 如何在SunPKCS11中获取 session 句柄

标签 java security hsm

我正在使用 SoftHSM,并且能够生成 key 并将其存储在 token 中。为了使用 SunPKCS 接口(interface),许多方法都需要 session 句柄,但我不知道如何检索它们。 目前我正在使用 SoftHSM 和 PKCS11,如下所示。注释中的代码是我尝试使用 SUNPKCS11 接口(interface)签名的代码。 任何有关如何包装和解开 key 的示例代码也将不胜感激。我正在尝试使用 PKCS11 将 key 从一个 token 备份到另一个 token ,如果我的理解是正确的,则该方法必须通过包装...... 西塔拉曼

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();
    }
}

最佳答案

您可以使用 SunPKCS11 包装器中的方法,就像在示例代码中的注释 block 中所做的那样。

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

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 key 并获取生成 key 的句柄,请使用以下内容(作为示例):

        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)
        {
        }

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

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

关于java - 如何在SunPKCS11中获取 session 句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21201697/

相关文章:

java - sunpkcs11 支持使用 ECDH 派生 key 的 CK_sensitive 属性

java - Spring boot - 错误的 TCP 连接处理

java - 使用 PhantomJS headless 浏览器切换 iframe 时数组索引越界异常 -1

php - 使用 cookie 限制访问

javascript - 为什么同一个 HSM key 每次都会验证到不同的以太坊地址?

hsm - Pkcs11异常 : Method C_Initialize returned 2147483907

java - apache Camel 混合组件

java - 如何仅在其他规则被触发时才触发规则?

关于本地主机 repo 中私钥的安全相关问题

android - 防止 ios 应用程序出现 "fake-client"