2016-06-16 9 views
9

Mam zainicjowany przez dostawcę SunPKCS11:Jak sfinalizować dostawcę SunPKCS11 po zainicjowaniu?

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

A potem używam tego dostawcę zainicjować KeyStore użyć klucza do operacji szyfrowania.

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

Kiedy skończę z szyfrowania operacji jak mam zakończyć sesję z tokena pkcs11?

Próbowałem usunąć dostawcę, ale nie zadziałało.

Security.removeProvider("sunPCKS11ProviderName"); 

Następnym razem postaram się komunikować z tokenem, otrzymuję ten wyjątek wyrzucony z tokena CKR_CRYPTOKI_ALREADY_INITIALIZED

UPDATE:

próbowałem

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

ale to też nie działa.

Mam przypadek użycia, w którym muszę używać zarówno Wrapper i Provider PKCS # 11. Aby móc korzystać z opakowania, muszę sfinalizować dostawcę, albo też token zgłasza błąd CKR_CRYPTOKI_ALREADY_INITIALIZED, gdy opakowanie próbuje się komunikować z tokenem.

aktualizacja z KOD:

Używam PKCS # 11 Provider Sun i IAIK za PKCS # 11 owijki.

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

Ponieważ dostawca firmy Sun nie wylogowuje się i nie zamyka sesji, IAIK nie może uzyskać dostępu do tokena. A aplet Java Keystore nie ma metody wylogowania.

+0

Dlaczego zainicjowałbyś token kilka razy? Utwórz singleton w swoim projekcie, który będzie działał z tokenem i zainicjuj dostawcę podczas tworzenia singletonu. –

+0

Inicjuję token (przy użyciu dostawcy) na singleton. Ale mam przypadek użycia, w którym muszę komunikować się z tokenem przy użyciu Wrappera PKCS # 11. Podczas tej inicjalizacji token wyrzuca już zainicjowany wyjątek. –

Odpowiedz

3

Wreszcie udało się znaleźć rozwiązanie. Dostawca Słońca używa Podstępu pod spodem. Sztuczka polega więc na użyciu paczki PKCS # 11, aby uzyskać aktualną instancję i sfinalizować ją. Oczywiście to sfinalizowanie funkcji sesji nie jest ujawnione w usługodawcy. Ale istnieje obejście, a wygląda to tak:

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

Twoje są coraz to wyjątek, bo kiedyś program zostanie wykonany po raz pierwszy wartości zachował się z identyfikatorem procesu w java.So rozwiązać tę markę jako plik jar i uruchamiany jako plik wsadowy

+0

To nie było przyczyną problemu w mojej sprawie, była to finalizująca operacja z tokenem, która nie była dostępna w interfejsie java KeyStore/Provider. I to jest w mojej logice biznesowej, więc nie mogę jej użyć w pliku wsadowym. –

Powiązane problemy