Подтвердить что ты не робот

Загрузить MSCAPI Java Keystore без загрузки закрытых ключей (жесткий токен)

Я хотел бы загрузить MSCAPI keystore в Java и проверить доступные сертификаты в магазине MY. Однако некоторые ключи для этих сертификатов находятся на аппаратных токенах, а всплывающее окно запрашивает токен во время загрузки.

Есть ли способ отложить загрузку закрытых ключей при загрузке хранилища ключей Windows?

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

Ответ 1

Всплывающее окно активируется из поставщика криптографических услуг MS-CAPI (CSP) - DLL, поставляемого производителем маркера USB, который, наконец, обменивается данными с маркером через драйвер (также поставляемый производителем токенов). 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, чтобы избежать этого или иначе проиграть эту проверку.