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-MYWindows-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)

无声安装PFX到Android系统可信CA用户密钥库

Java keyTool - 将主要/次要中间证书附加到密钥库[关闭]

从证书、中间证书和私钥创建密钥库 [重复]

Android密钥库系统KeyStore