【问题标题】:Java access to intermediate CAs from Windows keystores?Java 从 Windows 密钥库访问中间 CA?
【发布时间】:2011-07-25 12:29:35
【问题描述】:

我需要在 Windows 上构建一个证书链,从 X.509 智能卡证书通过一个或多个中间 CA 到根 CA。当 CA 证书位于 JKS 密钥库中时,这很容易,但我也需要使用 Windows 密钥库。

我可以从“Windows-ROOT”获取根 CA 证书,但无法访问“中间证书颁发机构”密钥库。

有人做过吗?

谢谢!

【问题讨论】:

    标签: java windows x509certificate


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2013-10-27
      • 2021-12-24
      • 1970-01-01
      • 2018-12-14
      • 2011-04-06
      • 2014-09-12
      • 1970-01-01
      • 2015-05-02
      • 2014-09-14
      相关资源
      最近更新 更多