Accesso ai certificati di Windows Certificate Store tramite Java?


Sto cercando di scrivere qualcosa che possa enumerare e utilizzare (per firmare) i certificati in CurrentUser/My e LocalMachine/My, ma non sono stato in grado di trovare nulla per l'archivio cert di Windows, solo il negozio segreto di Java. Questo link sembra promettente, ma posso usare solo ciò che viene fornito con Java.

Ho trovato questa domanda posta su SO prima, ma è di cinque anni fa, che è molto tempo negli anni del computer. Grazie!

Author: Community, 2015-12-09

4 answers

La natura multipiattaforma di Java ha i suoi aspetti negativi: non è possibile accedere ad alcune (o molte) cose specifiche del sistema operativo senza librerie esterne. Windows certificate store è accessibile solo tramite funzioni native CryptoAPI che non sono supportate dall'installazione predefinita Java.

Puoi dare un'occhiata a questa discussione: Chiamando il metodo API Win32 da Java

Se è possibile utilizzare JNA, è possibile utilizzare varie funzioni Certificate e Certificate Store in crypt32.dll a enumerare i certificati ed eseguire operazioni di firma.

 1
Author: Crypt32, 2017-05-23 12:34:54
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
Author: Krzysiek, 2015-12-09 09:24:02

Ho scelto da dove Crypt32 sinistra, utilizzato JNA per accedere ai certificati utilizzando la stessa finestra di dialogo di Windows che si apre se si dovesse utilizzare qualsiasi programma specifico di Windows:

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

È solo un pezzo di codice che funziona; sentiti libero di applicare le tue pratiche di codifica.

 0
Author: Tech Junkie, 2017-02-07 11:20:46

Avvia Java con -Djavax.net.ssl.trustStoreType=WINDOWS-ROOT.

Vedere http://www.oracle.com/technetwork/articles/javase/security-137537.html per ulteriori informazioni.

 0
Author: michael.kebe, 2018-09-14 10:59:50