Load MSCAPI Java Keystore without loading private

2019-03-15 08:54发布

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 tokens and a popup asks for the token during load.

Is there a way to defer loading the private keys when loading the Windows keystore?

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

2条回答
forever°为你锁心
2楼-- · 2019-03-15 09:45

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.

查看更多
登录 后发表回答