2015-12-08 64 views
1

我正在尋找能夠枚舉和使用(簽名)CurrentUser/My和LocalMachine/My中的證書的東西,但是我一直無法找到Windows證書存儲區的任何內容,只有Java自己的祕密存儲區。 This link看起來很有希望,但我只能使用Java附帶的東西。通過Java訪問Windows證書存儲證書?

我發現this question之前被問過,但它是從五年前開始的,這在計算機年代已經很長時間了。謝謝!

回答

1

Java的跨平臺性質有它自己的缺點 - 你不能訪問一些(或許多)特定於操作系統的東西,而無需外部庫。 Windows證書存儲只能通過Java缺省安裝不支持的CryptoAPI本機函數訪問。

你可以看看這個線程:Calling Win32 API method from Java

如果你可以使用JNA,那麼您可以使用各種Certificate and Certificate Store Functions在crypt32.dll枚舉證書和執行簽名操作。

+0

JNA聽起來像是一個不錯的選擇......但我無法理解那裏的示例代碼。我不認爲你知道任何C#/ .NET的方法嗎? – Benjin

+0

我希望微軟通過允許非Windows Java通過組策略更新來讀取Windows服務器推送的信任存儲,從而表達了良好的願望。例如。提供從域服務器下載的PEM包:-) –

0
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

這是如何確定它正在枚舉的Windows證書存儲區內的哪個路徑?我期望在某處看到「LocalMachine」或「CurrentUser」。 – Benjin

+0

我想,你不能得到這個信息。但是,也許我錯了。讓我知道什麼時候你會想出這個。 – Krzysiek

0

我從Crypt32離開的地方挑,使用JNA使用相同的Windows對話框彈出來訪問證書,如果你使用任何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); 

它只是一塊有效的代碼;隨時應用您的編碼實踐。