Java 从 Windows 密钥库访问中间 CA?
Posted
技术标签:
【中文标题】Java 从 Windows 密钥库访问中间 CA?【英文标题】:Java access to intermediate CAs from Windows keystores? 【发布时间】:2011-07-25 12:29:35 【问题描述】:我需要在 Windows 上构建一个证书链,从 X.509 智能卡证书通过一个或多个中间 CA 到根 CA。当 CA 证书位于 JKS 密钥库中时,这很容易,但我也需要使用 Windows 密钥库。
我可以从“Windows-ROOT”获取根 CA 证书,但无法访问“中间证书颁发机构”密钥库。
有人做过吗?
谢谢!
【问题讨论】:
【参考方案1】:SunMSCAPI Cryptographic 提供程序仅支持两个密钥库:Windows-MY
(个人证书存储)和Windows-ROOT
(受信任的权威证书存储),因此我认为无法直接访问其他 Windows 证书存储。但是它可能不是必需的,因为Windows-MY
密钥库似乎能够使用来自其他商店的证书构建证书链。
这是我用来测试它的代码sn-p:
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。在中间 CA 证书存储中添加 CA 后,我再次启动程序,链长度现在为 2。
更新(4 月 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);
【讨论】:
是的,如果用户的证书在个人商店中就没有问题。我想知道我是否可以通过编程方式添加它? 行得通!我从智能卡中检索用户的证书,以编程方式将其添加到 Windows-MY 存储中,然后使用 Windows 密钥库构建链。【参考方案2】: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 证书链在构建时并未经过验证,但现在您可以执行通常的操作,即创建 CertPath 和 PKIXParameters 并使用它们来验证链。
CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
certPathValidator.validate(certPath, params);
【讨论】:
以上是关于Java 从 Windows 密钥库访问中间 CA?的主要内容,如果未能解决你的问题,请参考以下文章
来自 CA 的 PKCS12 Java 密钥库和 Java 中的用户证书
使用自签名证书部署Spring Boot应用程序(包括中间CA)