在Java中访问本地机器证书存储?

是否可以从Java Servlet访问存储在本地计算机存储(而不是当前用户)中的证书? 我已经尝试使用MSCAPI提供程序打开“Windows-MY”和“Windows-ROOT”存储,但都不包含来自本地计算机存储的证书。

默认的JDK实现相当有限。 AFAIK它只会带回RSA密钥和证书。 它不是MSCAPI的通用适配器。 我已经能够使用你描述的机制获得一些证书。

我使用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); 

这只是一段代码的作品; 随时应用您的编码实践。

您正在查找的证书位于java密钥库文件中,或者在启动服务器时传递给tomcat

http://tomcat.apache.org/tomcat-4.0-doc/ssl-howto.html

如果您试图在应用程序中加载它们,请在此处查看是否发出HTTPS请求,然后使用HTTPClient文档启动

http://www.jdocs.com/httpclient/3.0.1/api-index.html?m=class&p=org.apache.commons.httpclient.contrib.ssl&c=AuthSSLProtocolSocketFactory&render=classic

不知道这是否帮助你,但如果你能提供更多的细节,那么你可能会得到更具体的答案

 public class KeyStoreLookup { public static void main(String args[]) { try { KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); String fname = System.getProperty("user.home") + File.separator + ".keystore"; FileInputStream fis = new FileInputStream(fname); ks.load(fis, null); if (ks.isKeyEntry(args[0])) { System.out.println(args[0] + " is a key entry in the keystore"); char c[] = new char[args[1].length()]; args[1].getChars(0, c.length, c, 0); System.out.println("The private key for" + args[0] + " is " + ks.getKey(args[0], c)); Certificate certs[] = ks.getCertificateChain(args[0]); if (certs[0] instanceof X509Certificate) { X509Certificate x509 = (X509Certificate) certs[0]; System.out.println(args[0] + " is really " + x509.getSubjectDN()); } if (certs[certs.length - 1] instanceof X509Certificate) { X509Certificate x509 = (X509Certificate) certs[certs.length - 1]; System.out.println(args[0] + " was verified by " + x509.getIssuerDN()); } } else if (ks.isCertificateEntry(args[0])) { System.out.println(args[0] + " is a certificate entry in the keystore"); Certificate c = ks.getCertificate(args[0]); if (c instanceof X509Certificate) { X509Certificate x509 = (X509Certificate) c; System.out.println(args[0] + " is really " + x509.getSubjectDN()); System.out.println(args[0] + " was verified by " + x509.getIssuerDN()); } } else { System.out.println(args[0] + " is unknown to this keystore"); } } catch (Exception e) { e.printStackTrace(); } } }