как загрузить закрытый ключ в хранилище Windows с помощью Java KeyStore

Я работаю над этим проектом Java, где мне нужно загрузить закрытый ключ из хранилища ключей Windows с помощью провайдера SunMSCAPI, но я вообще не указываю пароль, я не знаю, нужно ли мне это делать. это пример теста того, что я делаю:

public static void main(String[] args) throws Throwable {
    Provider provider = Security.getProvider("SunMSCAPI");
    KeyStore wins=KeyStore.getInstance("Windows-MY", provider);
    wins.load(null, null);
    Enumeration<String> aliases = wins.aliases();
    while (aliases.hasMoreElements()) {
        String alias = (String) aliases.nextElement();
        System.out.println(alias);
        Certificate[] chain = wins.getCertificateChain(alias);
        X509Certificate[] x509 = CERManager.toX509(chain);
        for (int i = 0; i < x509.length; i++) {
            System.out.println(x509[i].getSubjectX500Principal());
        }
        Key key = wins.getKey(alias, "1234".toCharArray());
        System.out.println(key);

    }

}

когда я запускаю это, я получаю некоторый сертификат, который я ранее импортировал из файла pfx с помощью Adobe Reader, но я не могу получить закрытый ключ, соответствующий этому сертификату, вместо этого я просто получаю null.

любая помощь по этой проблеме? заранее спасибо


person Aramis Rodríguez Blanco    schedule 03.11.2017    source источник


Ответы (1)


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

private static void importPFX(File pfxFile, char pass[]) throws Exception {
    SunMSCAPI providerMSCAPI = new SunMSCAPI();
    Security.addProvider(providerMSCAPI);
    KeyStore wins=KeyStore.getInstance("Windows-MY", providerMSCAPI);
    wins.load(null, null);
    BouncyCastleProvider bcp = new BouncyCastleProvider();
    Security.addProvider(bcp);
    KeyStore pfx = KeyStore.getInstance("PKCS12","BC");
    pfx.load(new FileInputStream(pfxFile), pass);

    Enumeration<String> aliases = pfx.aliases();
    while (aliases.hasMoreElements()) {
        String alias = (String) aliases.nextElement();
        Certificate[] chain = pfx.getCertificateChain(alias);
        X509Certificate x509[]=new X509Certificate[chain.length];
        for (int i = 0; i < chain.length; i++) {
            x509[i]=(X509Certificate) chain[i];
        }
        X500Name x500name = new JcaX509CertificateHolder(x509[0]).getSubject();
        RDN cn = x500name.getRDNs(BCStyle.CN)[0];

        String commonName = IETFUtils.valueToString(cn.getFirst().getValue());
        PrivateKey pkey = (PrivateKey) pfx.getKey(alias, pass);
        System.out.println(pkey);
        wins.setKeyEntry(commonName, pkey, "1234".toCharArray(), new X509Certificate[]{x509[0]});
        wins.store(null, null);
    }
}

а затем я использовал первый код из вопроса, чтобы перечислить ключи и сертификаты хранилища ключей Windows, и я получил закрытый ключ в порядке.

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

person Aramis Rodríguez Blanco    schedule 03.11.2017