Java 从 Windows 密钥库访问中间 CA?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5476974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java access to intermediate CAs from Windows keystores?
提问by Mermeister
I need to build a certificate chain on Windows, from an X.509 smart card cert through one or more intermediate CAs to a root CA. That's easy when the CA certs are in a JKS keystore, but I need to use the Windows keystores as well.
我需要在 Windows 上构建一个证书链,从 X.509 智能卡证书到一个或多个中间 CA 到根 CA。当 CA 证书位于 JKS 密钥库中时,这很容易,但我也需要使用 Windows 密钥库。
I can get the root CA cert from "Windows-ROOT", but I can't get to the "Intermediate Certification Authorities" keystore.
我可以从“Windows-ROOT”获取根 CA 证书,但无法进入“中间证书颁发机构”密钥库。
Has anyone done this?
有没有人做过这个?
Thanks!
谢谢!
回答by Jcs
The SunMSCAPI Cryptographic provider does only support two keystores: Windows-MY
(personal certificate store) and Windows-ROOT
(trusted authorities certificate store), thus I don't thinks it is possible to directly access to other windows certificate stores. However it may not be necessart since it seems that the Windows-MY
keystore is able to build certificate chains with the certificates from other stores.
SunMSCAPI 加密提供程序仅支持两个密钥库:(Windows-MY
个人证书存储)和Windows-ROOT
(受信机构证书存储),因此我认为无法直接访问其他 Windows 证书存储。但是,它可能不是必需的,因为Windows-MY
密钥库似乎能够使用来自其他存储的证书构建证书链。
Here is a code snippet I use to test it:
这是我用来测试它的代码片段:
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);
}
}
If I add a single certificate with private key in the personal certificate store the chain length is 1. After adding the CA in the intermediate CA certificate store the I launch the program a second time and the chain length is now 2.
如果我在个人证书存储中添加带有私钥的单个证书,则链长为 1。在中间 CA 证书存储中添加 CA 后,我第二次启动该程序,链长现在为 2。
UPDATE (April, 2nd)It is possible to programmatically add certificates in the Windows-MY
and Windows-ROOT
keystore with some limitations:
更新(4 月 2 日)可以在Windows-MY
和Windows-ROOT
密钥库中以编程方式添加证书,但有一些限制:
- when adding a certificate in the
Windows-ROOT
the user is prompted for confirmation - all certificate added in the
Windows-MY
keystore is aTrustedCertificateEntry
(from the keystore point of view, not the Windows point of view). The keystore seems to build the longest possible chain with all available certificates. - the certifcates with no associated private key are not visible in the Windows certificate store browser but it is possible to programmatically delete them.
- 在用户中添加证书时,
Windows-ROOT
会提示用户进行确认 Windows-MY
密钥库中添加的所有证书都是一个TrustedCertificateEntry
(从密钥库的角度来看,而不是 Windows 的角度)。密钥库似乎使用所有可用证书构建了尽可能长的链。- 没有关联私钥的证书在 Windows 证书存储浏览器中不可见,但可以通过编程方式删除它们。
Adding a certificate in a keystore is straightforward:
在密钥库中添加证书很简单:
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);
回答by Mermeister
Jcs had the answer, but I want to show some pseudocode so:
Jcs 有答案,但我想展示一些伪代码,所以:
// load the Windows keystore
KeyStore winKeystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
winKeystore.load(null, null);
// add the user's smart card cert to the keystore
winKeystore.setCertificateEntry(myAlias, userCertificate);
// build the cert chain! this will include intermediate CAs
Certificate[] chain = winKeystore.getCertificateChain(myAlias);
Windows cert chains aren't validated as they're built, but now you can do the usual thing of creating a CertPath and PKIXParameters and using them to validate the chain.
Windows 证书链在构建时未经过验证,但现在您可以执行通常的操作,即创建 CertPath 和 PKIXParameters 并使用它们来验证链。
CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
certPathValidator.validate(certPath, params);