Java IAIK Pkcs11 Wrapper生成的密钥不会保留

时间:2017-11-19 14:13:59

标签: java pkcs#11

有人可以帮助解决以下问题吗?

我正在使用:

  • SoftHSM for Windows
  • IAIK Pkcs11 Java Wrapper(v.1.4)连接到SoftHSM

我的Java应用程序按以下步骤生成AES密钥:

  1. 打开PKCS11会话,登录执行。
  2. 成功生成AES密钥。
  3. 搜索此密钥 - 找到它。
  4. 结束会议。
  5. 但是如果我打开新会话,我就找不到密钥了 - 当我关闭会话时它就消失了,并且没有持久存在HSM。

    我做错了吗?

    申请代码是:

    import java.io.IOException;
    
    import iaik.pkcs.pkcs11.Mechanism;
    import iaik.pkcs.pkcs11.Module;
    import iaik.pkcs.pkcs11.Session;
    import iaik.pkcs.pkcs11.Slot;
    import iaik.pkcs.pkcs11.Token;
    import iaik.pkcs.pkcs11.TokenException;
    import iaik.pkcs.pkcs11.objects.AESSecretKey;
    import iaik.pkcs.pkcs11.objects.Object;
    import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
    
    public class GenerateKeyAes {
    
        public static void main(String[] args) throws IOException, TokenException {
    
            // Init module and select slot and token
            Module module = Module.getInstance("C:\\prog\\SoftHSM2\\lib\\softhsm2.dll");
            module.initialize(null);
            Slot slot = module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT)[0];
            Token token = slot.getToken();
    
            // Create session and login
            Session session = token.openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION,
                    null, null);
            session.login(Session.UserType.USER, "1111".toCharArray());
    
            // Prepare key template
            Mechanism keyGenerationMechanism = Mechanism.get(PKCS11Constants.CKM_AES_KEY_GEN);
    
            AESSecretKey secretKeyTemplate = new AESSecretKey();
            secretKeyTemplate.getValueLen().setLongValue(new Long(32));
            secretKeyTemplate.getLabel().setCharArrayValue("AES secret 1".toCharArray());
            secretKeyTemplate.getId().setByteArrayValue(new byte[] { 105 });
            secretKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
            secretKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
            secretKeyTemplate.getToken().setBooleanValue(Boolean.FALSE);
    
            // Create key
            AESSecretKey secretKey = (AESSecretKey) session.generateKey(keyGenerationMechanism, secretKeyTemplate);
    
            System.out.println("Key generated:");
            System.out.println(secretKey.toString());
            System.out.println();
    
            // Find all objects to ensure that generated key was really created
            AESSecretKey template = new AESSecretKey();
            session.findObjectsInit(template);
            Object[] obs = session.findObjects(10);
            System.out.println("Found objects: " + obs.length);
            System.out.println();
    
            // Key is found and displayed here!!!
            for (Object ob : obs) {
                System.out.println("Found object:");
                System.out.println(ob);
                System.out.println();
            }
    
            // Close session
            session.findObjectsFinal();
            session.closeSession();
    
            // If I open new session here and perform same search - no key is found!
    
            module.finalize(null);
        }
    }
    

1 个答案:

答案 0 :(得分:3)

PKCS#11对象可以按其生命周期和可见性进行分类:

  1. 令牌对象CKA_TOKEN属性设置为true的那些)。
    它们对连接到具有足够权限的令牌的所有应用程序都是可见的,并且即使在会话(应用程序和令牌之间的连接)关闭并且令牌从其插槽中移除后仍保留在令牌上。

  2. 会话对象CKA_TOKEN属性设置为false的人)
    它们更具临时性 - 只要会话以任何方式关闭,该会话创建的所有会话对象都将自动销毁。此外,会话对象仅对创建它们的应用程序可见。

  3. 我不熟悉IAIK包装器,但似乎您正在创建一个会话对象的密钥。

    我会尝试改变:

    secretKeyTemplate.getToken().setBooleanValue(Boolean.FALSE);
    

    secretKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
    

    有关详细信息,请参阅PKCS#11 v2.20 specification