Accessing Windows Certificate Store certs via Java?

前端 未结 4 1853
再見小時候
再見小時候 2020-12-09 18:46

I\'m looking to write something that can enumerate and use (to sign) certificates in CurrentUser/My and LocalMachine/My, but I haven\'t been able to find anything for the Wi

相关标签:
4条回答
  • 2020-12-09 19:30

    The cross-platform nature of the Java has its own downsides -- you cannot access some (or many) OS-specific things without external libraries. Windows certificate store is accessible only via CryptoAPI native functions which are not support by Java default installation.

    You may take a look at this thread: Calling Win32 API method from Java

    If you can use JNA, then you can use various Certificate and Certificate Store Functions in crypt32.dll to enumerate certificates and perform signing operations.

    0 讨论(0)
  • 2020-12-09 19:32

    Start Java with -Djavax.net.ssl.trustStoreType=WINDOWS-ROOT.

    See https://www.oracle.com/technical-resources/articles/javase/security.html for more information.

    0 讨论(0)
  • 2020-12-09 19:33
    KeyStore keyStore = KeyStore.getInstance(getKeyStoreType(), "SunMSCAPI");
    keyStore.load(null, null);
    
    try {
        Field field = keyStore.getClass().getDeclaredField("keyStoreSpi");
        field.setAccessible(true);
    
        KeyStoreSpi keyStoreVeritable = (KeyStoreSpi)field.get(keyStore);
        field = keyStoreVeritable.getClass().getEnclosingClass().getDeclaredField("entries");
        field.setAccessible(true);
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, "Set accessible keyStoreSpi problem", e);
    }
    
    Enumeration enumeration = keyStore.aliases();
    
    0 讨论(0)
  • 2020-12-09 19:46

    I picked from where Crypt32 left, used JNA to access the certificates using the same windows dialog that pops up if you were to use any windows specific program:

        NativeLibrary cryptUI = NativeLibrary.getInstance("Cryptui");
        NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32");
    
        Function functionCertOpenSystemStore = crypt32.getFunction("CertOpenSystemStoreA");
        Object[] argsCertOpenSystemStore = new Object[] { 0, "CA"};
        HANDLE h = (HANDLE) functionCertOpenSystemStore.invoke(HANDLE.class, argsCertOpenSystemStore);
    
        Function functionCryptUIDlgSelectCertificateFromStore = cryptUI.getFunction("CryptUIDlgSelectCertificateFromStore");
        System.out.println(functionCryptUIDlgSelectCertificateFromStore.getName());
        Object[] argsCryptUIDlgSelectCertificateFromStore = new Object[] { h, 0, 0, 0, 16, 0, 0};
        Pointer ptrCertContext = (Pointer) functionCryptUIDlgSelectCertificateFromStore.invoke(Pointer.class, argsCryptUIDlgSelectCertificateFromStore);
    
        Function functionCertGetNameString = crypt32.getFunction("CertGetNameStringW");
        char[] ptrName = new char[128];
        Object[] argsCertGetNameString = new Object[] { ptrCertContext, 5, 0, 0, ptrName, 128};
        functionCertGetNameString.invoke(argsCertGetNameString);
        System.out.println("Selected certificate is " + new String(ptrName));
    
        Function functionCertFreeCertificateContext = crypt32.getFunction("CertFreeCertificateContext");
        Object[] argsCertFreeCertificateContext = new Object[] { ptrCertContext};
        functionCertFreeCertificateContext.invoke(argsCertFreeCertificateContext);
    
        Function functionCertCloseStore = crypt32.getFunction("CertCloseStore");
        Object[] argsCertCloseStore = new Object[] { h, 0};
        functionCertCloseStore.invoke(argsCertCloseStore);
    

    It is just a piece of code that works; feel free to apply your coding practices.

    0 讨论(0)
提交回复
热议问题