2010-08-31 67 views
4

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

+0

你在这里获得了你想要的吗?我有同样的问题,根本没有运气。 – skw 2011-12-19 23:12:59

+0

@skw不,我从来没有能够从纯Java获取本地机器证书,我最终使用Entrust的提供程序(它执行JNI调用)来检索我需要的证书。 – 2011-12-20 14:56:50

+0

谢谢你的回复。太糟糕了,它不是Java本地的。我认为这可能是一些安全问题。 – skw 2011-12-20 19:13:27

回答

-1

你正在寻找的证书是在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

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

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(); 
     } 
    } 
} 
+1

我不打算做SSL。我想访问机器证书并取出密钥对来加密/解密配置文件中的某些设置。我已经使用当前用户的个人证书存储中的证书完成了此操作,但是我希望将(SSL)证书从加密的本地计算机存储中取出。 – 2010-08-31 20:58:22

+1

这段代码根本不是OP所要求的。 – Justin 2010-09-03 14:51:23

2

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

+0

我要的只是RSA密钥对。你是对的,我可以从当前用户的个人(Windows-MY)商店获得密钥对,但是我希望从本地计算机的个人证书商店获得它们。我没有找到一种方法来指定读取哪个证书存储区(当前用户/本地计算机)。它似乎只想从当前用户读取。 – 2010-08-31 21:00:05

+0

我看到你想要做的,但是:为什么它应该让你从其他用户的商店阅读?本地机器在其商店中是否有密钥对? - 如果是这样的话,你的java进程需要作为操作系统一部分的权限。 – Justin 2010-08-31 22:16:49

+0

是本地机器在其商店中有一个密钥对;任何想法如何我可以给我的Java进程权限作为操作系统的一部分? – 2010-09-01 13:34:21

2

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

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

+0

如何使用这种方式获取PrivateKey提供程序? – codenamezero 2017-10-25 21:15:05

相关问题