Поставщик SunMSCAPI Cryptographic поддерживает только два хранилища ключей: Windows-MY
(хранилище личных сертификатов) и Windows-ROOT
(хранилище сертификатов доверенных органов), поэтому я не думаю, что возможен прямой доступ к другим хранилищам сертификатов Windows. Однако это может не потребоваться, поскольку кажется, что Windows-MY
хранилище ключей может создавать цепочки сертификатов с сертификатами из других хранилищ.
Вот фрагмент кода, который я использую для проверки:
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null) ;
Enumeration en = ks.aliases() ;
while (en.hasMoreElements()) {
String aliasKey = (String)en.nextElement() ;
Certificate c = ks.getCertificate(aliasKey) ;
System.out.println("---> alias : " + aliasKey) ;
if (ks.isKeyEntry(aliasKey)) {
Certificate[] chain = ks.getCertificateChain(aliasKey);
System.out.println("---> chain length: " + chain.length);
for (Certificate cert: chain) {
System.out.println(cert);
}
}
Если я добавляю один сертификат с закрытым ключом в хранилище личных сертификатов, длина цепочки равна 1. После добавления СА в промежуточное хранилище сертификатов ЦС я запускаю программу второй раз, а длина цепочки теперь равна 2.
ОБНОВЛЕНИЕ (2 апреля)
Можно программно добавлять сертификаты в хранилище ключей Windows-MY
и Windows-ROOT
с некоторыми ограничениями:
- при добавлении сертификата в
Windows-ROOT
пользователю предлагается подтверждение
- все сертификаты, добавленные в хранилище ключей
Windows-MY
, представляют собой TrustedCertificateEntry
(с точки зрения хранилища ключей, а не с точки зрения Windows). Склад ключей, похоже, создает самую длинную цепочку из всех доступных сертификатов.
- сертификаты без ассоциированного закрытого ключа не отображаются в браузере хранилища сертификатов Windows, но их можно программно удалить.
Добавить сертификат в хранилище ключей просто:
Certificate c = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream("C:/Users/me/Downloads/myca.crt"));
KeyStore.TrustedCertificateEntry entry = new KeyStore.TrustedCertificateEntry(c);
ks.setEntry("CA1", entry , null);