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

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

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

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

2 ответа

Решение

Всплывающее окно активируется из MS-CAPI Cryptographic Service Provider (CSP) - библиотеки DLL, поставляемой производителем USB-токена, - которая в итоге обменивается данными с токеном через драйвер (также предоставленный производителем токена). KeyStore просто выполняет вызов, а промежуточные слои просто пропускают его; микропрограмма на токене выдает всплывающее окно аутентификации и поддерживает состояние сеанса и т. д.

Ключевой Java-файл является 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, чтобы избежать этого или иным образом отменить эту проверку.

Другие вопросы по тегам