我正在寻找可以枚举和使用(签署)CurrentUser / My和LocalMachine / My中的证书的东西,但是我无法找到任何Windows证书库,只有Java自己的秘密商店。 This link看起来很有前途,但我只能使用Java附带的东西。
我之前发现this question问过这个问题,但这是五年前的事,那是计算机时代的一段时间。谢谢!
用-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT
启动Java。
有关更多信息,请参阅http://www.oracle.com/technetwork/articles/javase/security-137537.html。
Java的跨平台特性有其自身的缺点 - 如果没有外部库,您无法访问某些(或许多)特定于操作系统的内容。 Windows证书存储只能通过Java默认安装不支持的CryptoAPI本机函数访问。
你可以看一下这个帖子:Calling Win32 API method from Java
如果您可以使用JNA,那么您可以在crypt32.dll中使用各种Certificate and Certificate Store Functions来枚举证书并执行签名操作。
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();
我从Crypt32离开的地方选择,使用JNA来访问证书,如果您要使用任何特定于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);
它只是一段有效的代码;随意应用您的编码实践。