Load MSCAPI Java Keystore without loading private keys (hard token)

后端 未结 2 990
不思量自难忘°
不思量自难忘° 2021-02-05 17:02

I would like to load a MSCAPI keystore within Java and examine available certificates in the MY store. However some keys for those certificates reside on hardware

相关标签:
2条回答
  • 2021-02-05 17:42

    This issue has been solved in JDK 9.

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

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

    0 讨论(0)
  • 2021-02-05 17:50

    The popup is being activated from the MS-CAPI Cryptographic Service Provider (CSP) - the DLL supplied by the USB token manufacturer - which finally communicates to the token through a driver (also supplied by the token-manufacturer). KeyStore merely makes a call and the layers in between just pass it through; the firmware on the token is the one that throws up the authentication pop-up and maintains session-state, etc.

    The key Java dll is sunmscapi.dll which has the implementation:

    // 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;
        }
        ....
    

    As you can see it always checks for a private key. You would have to modify this code and create a custom version of sunmscapi.dll to avoid this or otherwise defeat this check.

    0 讨论(0)
提交回复
热议问题