Java access to intermediate CAs from Windows keystores?

后端 未结 2 892
闹比i
闹比i 2020-12-06 12:02

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

相关标签:
2条回答
  • 2020-12-06 12:25

    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.

    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.

    UPDATE (April, 2nd) It is possible to programmatically add certificates in the Windows-MY and Windows-ROOT keystore with some limitations:

    • when adding a certificate in the Windows-ROOT the user is prompted for confirmation
    • all certificate added in the Windows-MY keystore is a TrustedCertificateEntry (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.

    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);
    
    0 讨论(0)
  • 2020-12-06 12:34

    Jcs had the answer, but I want to show some pseudocode so:

    // 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.

    CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
    certPathValidator.validate(certPath, params);
    
    0 讨论(0)
提交回复
热议问题