加载MSCAPI Java密钥库而不加载私钥(硬令牌)

ems*_*rth 12 java keystore smartcard

我想MSCAPI keystore在Java中加载一个并检查MY商店中的可用证书.但是,这些证书的某些密钥驻留在硬件令牌上,并且弹出窗口在加载期间要求令牌.

有没有办法在加载Windows密钥库时推迟加载私钥?

keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null,null);
Run Code Online (Sandbox Code Playgroud)

Tyl*_*den 7

弹出窗口正在从MS-CAPI加密服务提供程序(CSP)激活 - 由USB令牌制造商提供的DLL - 最终通过驱动程序(也由令牌制造商提供)与令牌通信.KeyStore只是一个调用,其间的层只是通过它; 令牌上的固件是抛出身份验证弹出窗口并保持会话状态等的固件.

关键的Java DLL是sunmscapi.dll,它具有以下功能:

// 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;
    }
    ....
Run Code Online (Sandbox Code Playgroud)

如您所见,它始终检查私钥.您必须修改此代码并创建sunmscapi.dll的自定义版本以避免此问题或以其他方式破坏此检查.