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

时间:2012-10-17 15:15:11

标签: java keystore smartcard

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

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

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

2 个答案:

答案 0 :(得分: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;
    }
    ....

如您所见,它始终检查私钥。您必须修改此代码并创建自定义版本的sunmscapi.dll以避免此情况或以其他方式使此检查无效。

答案 1 :(得分:1)