Access Windows Certificate Store certificates through Java?

I want to write something that can list and use (sign) certificates in CurrentUser / My and LocalMachine / My, but I could not find anything for the Windows certificate store, but only for my own secret Java store. This link looks promising but I can only use what comes with Java.

I found this question asked on SO before, but it is from five years ago that a long time in computer years. Thank!

+2
source share
3 answers

The cross-platform nature of Java has its own drawbacks - you cannot access some (or many) OS-specific objects without external libraries. The Windows certificate store is only available through the native CryptoAPI features that are not supported by the default Java installation.

You can take a look at this topic: Calling the Win32 API Method from Java

If you can use JNA, you can use the various Certificate and certificate store functions in crypt32.dll to enumerate certificates and perform signature operations.

+1
source
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
source

I selected from Crypt32 to the left, used JNA to access certificates using the same window dialog that appears if you have to use any special Windows 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);

This is only the part of the code that works; Feel free to apply your coding methods.

0
source

Source: https://habr.com/ru/post/1536569/


All Articles