2016-06-16 18 views
9

私はでSunPKCS11プロバイダを初期化していますSunPKCS11プロバイダを初期化した後にファイナライズする方法は?

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

そして私は、暗号操作のためのキーを使用するキーストアを初期化するために、このプロバイダを使用しています。私は暗号操作で終わりだたら

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

は、はどのように私は、PKCS11トークンとのセッションを確定する必要がありますか?

私はプロバイダを削除しようとしましたが、機能しませんでした。

Security.removeProvider("sunPCKS11ProviderName"); 

私はトークンと通信しようとする次回は、私は、この例外は、トークンCKR_CRYPTOKI_ALREADY_INITIALIZED

UPDATEからスローされます:私は試してみました

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

でも動作しませんでした。

私はPKCS#11ラッパーとプロバイダの両方を使用する必要があるユースケースがあります。ラッパーを使用できるようにするには、プロバイダーをファイナライズする必要があります。そうでないと、ラッパーがトークンと通信しようとしているときにトークンがCKR_CRYPTOKI_ALREADY_INITIALIZEDエラーをスローします。

CODE WITH UPDATE:

私は、SunのPKCS#11プロバイダとIAIKのPKCS#11ラッパーを使用しています。

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にはログアウトする方法がありません。

+0

なぜトークンを何回も初期化しますか?プロジェクト内でシングルトンを作成します。シングルトンはトークンで動作し、シングルトン作成時にプロバイダを初期化します。 –

+0

シングルトンでトークン(プロバイダを使用)を初期化しています。しかし、PKCS#11 Wrapperを使用してトークンと通信する必要があるユースケースがあります。この初期化の間、トークンは既に初期化された例外をスローしています。 –

答えて

3

最後に解決策を見つけることができました。 Sunのプロバイダは、下にWrapperを使用します。だから、このトランクは、SunのPKCS#11ラッパーを使って現在のインスタンスを取得し、ファイナライズすることです。明らかに、このセッション機能のこのファイナライズはプロバイダでは公開されていません。しかし、そこに回避策はあり、それは次のようになります。

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

プログラムが最初に実行得れば値がこのメイクを解決するためにjava.SoでプロセスIDを保持しますので、あなたは、この例外を得ていますそれはjarファイルとして実行され、バッチファイルとして実行されます

+0

それは私のケースで問題を引き起こしたものではなく、java KeyStore/Provider APIを通じて利用できなかったトークンを使用したファイナライズ操作でした。これは私のビジネスロジックにあるので、バッチファイルでは使用できません。 –

関連する問題