编程语言
首页 > 编程语言> > java – 初始化后如何完成SunPKCS11 Provider?

java – 初始化后如何完成SunPKCS11 Provider?

作者:互联网

我通过以下方式初始化了SunPKCS11提供商:

Provider provider = new sun.security.pkcs11.SunPKCS11("path_to_pkcs11.cfg");
Security.addProvider(provider);

然后我使用此提供程序初始化KeyStore以使用密钥进行密码操作.

KeyStore ks = KeyStore.getInstance("PKCS11", provider);
ks.load(null, "password".toCharArray());

完成密码操作后,如何使用PKCS11令牌完成会话?

我试过删除提供程序,但它没有用.

Security.removeProvider("sunPCKS11ProviderName");

下次我尝试与令牌进行通信时,我会从令牌CKR_CRYPTOKI_ALREADY_INITIALIZED中抛出此异常

更新:

我努力了

sun.security.pkcs11.SunPKCS11.logout();

但它也没有用.

我有一个用例,我必须使用PKCS#11 Wrapper和Provider.为了能够使用包装器,我必须完成提供程序,否则当包装器尝试与令牌通信时,令牌会抛出CKR_CRYPTOKI_ALREADY_INITIALIZED错误.

更新代码:

我正在使用Sun的PKCS#11 Provider和IAIK的PKCS#11 Wrapper.

public static void providerAndWrapperIssue() throws Exception
{
    final String name = "ANY_NAME";
    final String library = "LOCATION OF THE TOKENS DLL/SO";
    final String slot = "SLOT NUMBER";

    // SUN PKCS#11 Provider -------------------------------------------

    StringBuilder builder = new StringBuilder();
    builder.append("name=" + name);
    builder.append(System.getProperty("line.separator"));
    builder.append("library=\"" + library + "\"");
    builder.append(System.getProperty("line.separator"));
    builder.append("slot=" + slot);

    ByteArrayInputStream bais = new ByteArrayInputStream(builder.toString().getBytes());
    Provider provider = new sun.security.pkcs11.SunPKCS11(bais);
    Security.addProvider(provider);

    KeyStore ks = KeyStore.getInstance("PKCS11");
    ks.load(null, null);

    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements())
        System.out.println(aliases.nextElement());

    // IAIK PKCS#11 Wrapper -------------------------------------------

    Module pkcs11Module = Module.getInstance(library, false);
    pkcs11Module.initialize(null); <-- Exception here.

    Slot[] slots = pkcs11Module.getSlotList(true);

    Session session = slots[0].getToken().openSession(true, true, null, null);
    session.login(Session.UserType.USER, "".toCharArray());

    session.logout();
    session.closeSession();

    slots[0].getToken().closeAllSessions();

    pkcs11Module.finalize(null);
}

由于Sun的提供程序未注销和关闭会话,因此IAIK无法访问该令牌. Java的Keystore api没有注销方法.

解决方法:

终于能够找到解决方案. Sun的提供商使用下面的包装器.所以诀窍是使用Sun的PKCS#11 Wrapper获取当前实例,并最终确定它.显然,会话功能的最终确定不会在提供程序中公开.但有一个解决方法,它看起来像这样:

public static void providerAndWrapperIssue() throws Exception
{
    final String name = "ANY_NAME";
    final String library = "LOCATION OF THE TOKENS DLL/SO";
    final String slot = "SLOT NUMBER";

    // SUN PKCS#11 Provider -------------------------------------------

    StringBuilder builder = new StringBuilder();
    builder.append("name=" + name);
    builder.append(System.getProperty("line.separator"));
    builder.append("library=\"" + library + "\"");
    builder.append(System.getProperty("line.separator"));
    builder.append("slot=" + slot);

    ByteArrayInputStream bais = new ByteArrayInputStream(builder.toString().getBytes());
    Provider provider = new sun.security.pkcs11.SunPKCS11(bais);
    provider.setProperty("pkcs11LibraryPath", library);
    Security.addProvider(provider);

    KeyStore ks = KeyStore.getInstance("PKCS11");
    ks.load(null, null);

    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements())
        System.out.println(aliases.nextElement());

    // ====================================
    // Solved it using the SUN PKCS#11 Wrapper

    PKCS11 pkcs11 = PKCS11.getInstance(((sun.security.pkcs11.SunPKCS11) provider).getProperty("pkcs11LibraryPath"), null, null, true);
    pkcs11.C_Finalize(PKCS11Constants.NULL_PTR);

    // ====================================

    // IAIK PKCS#11 Wrapper -------------------------------------------

    Module pkcs11Module = Module.getInstance(library, false);
    pkcs11Module.initialize(null);

    Slot[] slots = pkcs11Module.getSlotList(true);

    Session session = slots[0].getToken().openSession(true, true, null, null);
    session.login(Session.UserType.USER, "".toCharArray());

    session.logout();
    session.closeSession();

    slots[0].getToken().closeAllSessions();

    pkcs11Module.finalize(null);
}

标签:pkcs11,java,hsm
来源: https://codeday.me/bug/20190929/1829869.html