Apache HTTP客户端服务器TLS实现:获取密钥库异常

时间:2015-02-06 08:32:15

标签: java apache https apache-httpclient-4.x

服务器端:

  1. 我在Tomcat上部署了安全的RESTful服务,并启用了HTTPS协议。
  2. 我使用keytool.

  3. 创建了一个Keystore serverkeystore文件
  4. 从serverkeystore导出servercertificate.cer。

  5. 客户端:

    1. 创建了客户端密钥库clientkeystore.jsk

    2. 在clientkeystore.jsk中导入servercertificate.cer

    3. 从clientkeystore.jsk导出clientcertificate.cer。

    4. 在JAVA_HOME / lib / security下导入clientcertificate.cer

    5. 客户端代码中的例外:

      Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
      at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
      at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
      at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
      ... 30 more
      

      代码:

      private SSLConnectionSocketFactory buildSSLSocketFactory() throws Exception, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
          KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
          FileInputStream instream = new FileInputStream(new File("path to clientkeystore.jks"));
          try {
              trustStore.load(instream, "phhclient".toCharArray());
          } finally {
              instream.close();
          }
          // Trust own CA and all self-signed certs
          SSLContext sslcontext = SSLContexts.custom()
                  .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
                  .build();
          // Allow TLSv1 protocol only
          SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                  sslcontext,
                  new String[] { "TLSv1" },
                  null,
                  SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
      
      
          return sslsf;
      }
      

      无法找到所请求目标的有效证书路径 请告诉我为什么我得到例外

      谢谢和问候,

      Rahul Jain

1 个答案:

答案 0 :(得分:0)

此异常的原因是代码无法在客户端的信任库中找到服务器证书。请检查服务器证书是否已添加到客户端信任库。此外,TrustManagerFactory未在函数中实例化。

以下代码可用于构建SSL Socket Factory。请包括必要的进口声明:

SSLSocketFactory buildSSLSocketFactory() throws Exception {
    SSLContext sslcontext = null;

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    KeyStore trustks = KeyStore.getInstance("JKS");
    File trustcert = new File("path to truststore");
    InputStream truststream = new FileInputStream(trustcert);
    trustks.load(truststream, "password".toCharArray());
    truststream.close();
    tmf.init(trustks);

    try {
        sslcontext = SSLContext.getInstance("TLS");

        sslcontext.init(new KeyManager[0],
                 tmf.getTrustManagers() ,
                new SecureRandom());
    } catch (NoSuchAlgorithmException e) {  
        System.out.println("Exception  :"+e);       
    } catch (KeyManagementException e) {
        System.out.println("Exception  :"+e);   
    }

    SSLSocketFactory factory = sslcontext.getSocketFactory();

    return factory; 
}