Pytanie Załaduj JavaCAPI Java Keystore bez ładowania kluczy prywatnych (twardy token)


Chciałbym załadować MSCAPI keystore w Javie i sprawdź dostępne certyfikaty w sklepie MY. Jednak niektóre klucze dla tych certyfikatów znajdują się na tokenach sprzętowych, a okno popup pyta o token podczas ładowania.

Czy istnieje sposób na odroczenie ładowania kluczy prywatnych podczas ładowania magazynu kluczy Windows?

keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null,null);

12
2017-10-17 15:15


pochodzenie


To pytanie nie wzbudzi dużego zainteresowania emsworth, może zapytaj na forach Oracle (link do tego pytania). - Maarten Bodewes


Odpowiedzi:


Wyskakujące okienko jest aktywowane z dostawcy usług kryptograficznych MS-CAPI (CSP) - biblioteki DLL dostarczanej przez producenta tokena USB - który w końcu komunikuje się z tokenem za pośrednictwem sterownika (również dostarczanego przez producenta tokena). KeyStore po prostu wykonuje połączenie, a warstwy pośrednie po prostu przekazują je; oprogramowanie układowe tokenu wyrzuca okienko uwierzytelniania i utrzymuje stan sesji itp.

Kluczową biblioteką Java jest plik sunmscapi.dll, który ma implementację:

// Use CertEnumCertificatesInStore to get the certificates
// from the open store. pCertContext must be reset to
// NULL to retrieve the first certificate in the store.
while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
{
    // Check if private key available - client authentication certificate
    // must have private key available.
    HCRYPTPROV hCryptProv = NULL;
    DWORD dwKeySpec = 0;
    HCRYPTKEY hUserKey = NULL;
    BOOL bCallerFreeProv = FALSE;
    BOOL bHasNoPrivateKey = FALSE;
    DWORD dwPublicKeyLength = 0;

    if (::CryptAcquireCertificatePrivateKey(pCertContext, NULL, NULL,
                                            &hCryptProv, &dwKeySpec, &bCallerFreeProv) == FALSE)
    {
        bHasNoPrivateKey = TRUE;

    } else {
        // Private key is available

    BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey);

    // Skip certificate if cannot find private key
    if (bGetUserKey == FALSE)
    {
        if (bCallerFreeProv)
            ::CryptReleaseContext(hCryptProv, NULL);

        continue;
    }
    ....

Jak widać, zawsze sprawdza klucz prywatny. Będziesz musiał zmodyfikować ten kod i utworzyć niestandardową wersję pliku sunmscapi.dll, aby tego uniknąć lub w inny sposób pokonać to sprawdzenie.


7
2017-10-31 19:56



Obawiałem się, że tak było. Ostatecznie potrzebowałem interfejsu z tokenem sprzętowym, więc skończyło się na użyciu smartcardio do bezpośredniej komunikacji z tokenem aktualnie umieszczonym w terminalu. Magazyn zaufanych certyfikatów Java próbował załadować klucze prywatne dla tokenów, które zostały wcześniej wstawione do komputera, co było dla mnie nie do przyjęcia. - emsworth
Ciekawe ... dzięki kartom SmartCard mogę załadować plik kluczy bez pytania o token: keyStore = KeyStore.getInstance ("Windows-MY"); keystore.load (null, null); Chyba zależy to od dostawcy oprogramowania. - jBilbo


Ten problem został rozwiązany w JDK 9.

https://bugs.openjdk.java.net/browse/JDK-8153438

http://hg.openjdk.java.net/jdk9/dev/jdk/rev/e7f78523d41d


-1
2018-05-30 13:59