Доступ к хранилищу сертификатов локального компьютера на Java? - PullRequest
5 голосов
/ 01 сентября 2010

Можно ли получить доступ к сертификатам, хранящимся в хранилище локального компьютера (а не к текущему пользователю), из сервлета Java? Я попытался с помощью поставщика MSCAPI открыть хранилища «Windows-MY» и «Windows-ROOT», но ни один из них не содержит сертификатов из хранилища «Локальный компьютер».

Ответы [ 4 ]

3 голосов
/ 07 февраля 2017

Я использовал JNA для доступа к сертификатам с помощью того же диалогового окна Windows, которое появляется, если вы должны использовать какую-либо специальную программу для Windows - это может не отвечать на ваш вопрос, но, безусловно, позволяет вам предоставить возможность доступа к чему-либо "способом Windows «:

    NativeLibrary cryptUI = NativeLibrary.getInstance("Cryptui");
    NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32");

    Function functionCertOpenSystemStore = crypt32.getFunction("CertOpenSystemStoreA");
    Object[] argsCertOpenSystemStore = new Object[] { 0, "CA"};
    HANDLE h = (HANDLE) functionCertOpenSystemStore.invoke(HANDLE.class, argsCertOpenSystemStore);

    Function functionCryptUIDlgSelectCertificateFromStore = cryptUI.getFunction("CryptUIDlgSelectCertificateFromStore");
    System.out.println(functionCryptUIDlgSelectCertificateFromStore.getName());
    Object[] argsCryptUIDlgSelectCertificateFromStore = new Object[] { h, 0, 0, 0, 16, 0, 0};
    Pointer ptrCertContext = (Pointer) functionCryptUIDlgSelectCertificateFromStore.invoke(Pointer.class, argsCryptUIDlgSelectCertificateFromStore);

    Function functionCertGetNameString = crypt32.getFunction("CertGetNameStringW");
    char[] ptrName = new char[128];
    Object[] argsCertGetNameString = new Object[] { ptrCertContext, 5, 0, 0, ptrName, 128};
    functionCertGetNameString.invoke(argsCertGetNameString);
    System.out.println("Selected certificate is " + new String(ptrName));

    Function functionCertFreeCertificateContext = crypt32.getFunction("CertFreeCertificateContext");
    Object[] argsCertFreeCertificateContext = new Object[] { ptrCertContext};
    functionCertFreeCertificateContext.invoke(argsCertFreeCertificateContext);

    Function functionCertCloseStore = crypt32.getFunction("CertCloseStore");
    Object[] argsCertCloseStore = new Object[] { h, 0};
    functionCertCloseStore.invoke(argsCertCloseStore);

Это просто кусок кода, который работает; не стесняйтесь применять свои методы кодирования.

2 голосов
/ 01 сентября 2010

Реализация JDK по умолчанию довольно ограничена.AFAIK он вернет только ключи и сертификаты RSA.Это не универсальный адаптер для MSCAPI.Мне удалось вернуть некоторые сертификаты, используя описанный вами механизм.

1 голос
/ 06 августа 2018

Как уже упоминалось, поставщик MSCAPI не предоставляет доступ к сертификатам и ключам, хранящимся в хранилище сертификатов «Локальный компьютер».Причина этого заключается в том, что MSCAPI использует функцию Microsoft CryptoAPI CertOpenSystemStore для доступа к сертификатам и ключам.В документации для этой функции прямо указывается, что «При использовании этого метода доступны только сертификаты текущего пользователя, а не хранилище локального компьютера».Вы можете следить за этой ошибкой OpenJDK , если хотите отслеживать прогресс в этой проблеме.

Если вы хотите найти правильное решение проблемы, вы можете приобрести коммерческий Pheox JCAPI библиотека.

Если вы можете жить с взломом, я создал простую утилиту , которая перехватывает вызов JDK на CertOpenSystemStore и возвращает дескриптор виртуального хранилища сертификатов, разрешающего только чтениедоступ к сертификатам и ключам в хранилищах сертификатов «Текущий пользователь» и «Локальный компьютер».Это решило мою проблему, но помните об ограничениях этой утилиты.

0 голосов
/ 01 сентября 2010

Сертификаты, которые вы ищете, находятся в файле хранилища ключей Java или передаются в tomcat при запуске сервера

http://tomcat.apache.org/tomcat-4.0-doc/ssl-howto.html

, если вы пытаетесь загрузить их в свое приложение,затем посмотрите здесь, чтобы сделать HTTPS-запросы, тогда документация HTTPClient поможет вам начать

http://www.jdocs.com/httpclient/3.0.1/api-index.html?m=class&p=org.apache.commons.httpclient.contrib.ssl&c=AuthSSLProtocolSocketFactory&render=classic

, но вы не уверены, поможет ли это вам, но если вы можете предоставить больше информации,может быть в состоянии получить более конкретный ответ

public class KeyStoreLookup {
    public static void main(String args[]) {
        try {
            KeyStore ks = 
                      KeyStore.getInstance(KeyStore.getDefaultType());
            String fname = System.getProperty("user.home") +
                                File.separator + ".keystore";
            FileInputStream fis = new FileInputStream(fname);
            ks.load(fis, null);
            if (ks.isKeyEntry(args[0])) {
                System.out.println(args[0] +
                                " is a key entry in the keystore");
                char c[] = new char[args[1].length()];
                args[1].getChars(0, c.length, c, 0);
                System.out.println("The private key for" + args[0] + 
                            " is " + ks.getKey(args[0], c));
                Certificate certs[] = ks.getCertificateChain(args[0]);
                if (certs[0] instanceof X509Certificate) {
                    X509Certificate x509 = (X509Certificate) certs[0];
                    System.out.println(args[0] + " is really " +
                        x509.getSubjectDN());
                }
                if (certs[certs.length - 1] instanceof
                                     X509Certificate) {
                    X509Certificate x509 = (X509Certificate) 
                                        certs[certs.length - 1];
                    System.out.println(args[0] + " was verified by " +
                        x509.getIssuerDN());
                }
            }
            else if (ks.isCertificateEntry(args[0])) {
                System.out.println(args[0] +
                            " is a certificate entry in the keystore");
                Certificate c = ks.getCertificate(args[0]);
                if (c instanceof X509Certificate) {
                    X509Certificate x509 = (X509Certificate) c;
                    System.out.println(args[0] + " is really " +
                        x509.getSubjectDN());
                    System.out.println(args[0] + " was verified by " +
                        x509.getIssuerDN());
                }
            }
            else {
                System.out.println(args[0] +
                        " is unknown to this keystore");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...