Http客户端证书身份验证:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败

时间:2019-11-14 20:53:18

标签: java ssl https keystore client-certificates

我需要通过发送客户端和密钥证书来调用rest api。我创建了密钥库,如下所示:

openssl pkcs12 -export -in client_cert.pem -inkey client_key.key -out c:\kubectl\jaya\identity.p12
keytool -importkeystore -destkeystore identity.jks -deststorepass Tridium123 -srckeystore identity.p12 -srcstoretype PKCS12 -srcstorepass Tridium123

在下面的代码中,我尝试使用identity.jks和identity.p12进行操作,但是仍然存在相同的问题,客户端证书未发送到服务器。

Curl command and postman works good, but facing issues with Java
curl --request --insecure GET https://dkdk.com/api/v1/namespaces --cert client_cert.pem --key client_key.key

public static void main(String args[])
  {
    try
    {
      System.setProperty("javax.net.ssl.trustStore", "C://kubectl//nov12//trust.jks");
      System.setProperty("javax.net.ssl.keyStore", "C://kubectl//nov12//identity.p12");


      final String allPassword = "Password123";
      SSLContext sslContext = SSLContextBuilder.create()
        .loadKeyMaterial(new File("C://kubectl//nov12//identity.p12"), allPassword.toCharArray(), allPassword.toCharArray(), (aliases, socket) -> "mykey")
       .loadTrustMaterial(new File("C://kubectl//nov12//trust.jks"),  allPassword.toCharArray())
        .build();
      HttpClient client = HttpClients.custom()
        .setSSLContext(sslContext)
        .build();
      HttpGet get = new HttpGet("https://sdsds.com/api/v1/namespaces");
            HttpResponse response = client.execute(get);
      Arrays.asList(response.getAllHeaders()).stream().forEach(System.out::println);

      System.out.println(response.toString());

    }
    catch(Exception e){
      e.printStackTrace();
    }

以下是异常:

main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    02:16:09.103 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection
    02:16:09.104 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection discarded
    02:16:09.104 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://kaas-edge-admin.arm.com:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1640)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
        at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
        at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
        at com.example.demo.Sampletest.main(Sampletest.java:74)
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
        at sun.security.validator.Validator.validate(Validator.java:262)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1622)
        ... 21 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
        ... 27 more

    Process finished with exit code 0

我也尝试过以下方法,但还是没有运气:

 public static void main(String args[])throws Exception{
    PlainJavaHTTPS2Test pt = new PlainJavaHTTPS2Test();
    pt.testP12KeyStore();
  }

  public void testP12KeyStore() throws Exception {
    final String KEYSTOREPATH = "c:\\kubectl\\jaya\\identity.p12";
    final char[] KEYSTOREPASS = "Tridium123".toCharArray();
    final char[] KEYPASS = "Tridium123".toCharArray();

    try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) {
      setSSLFactories(storeStream, "PKCS12", KEYSTOREPASS, KEYPASS);
    }
    testPlainJavaHTTPS();
  }
  private static void setSSLFactories(InputStream keyStream, String keystoreType, char[] keyStorePassword, char[] keyPassword) throws Exception
  {
    KeyStore keyStore = KeyStore.getInstance(keystoreType);
    keyStore.load(keyStream, keyStorePassword);
    KeyManagerFactory keyFactory =
      KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyFactory.init(keyStore, keyPassword);
    KeyManager[] keyManagers = keyFactory.getKeyManagers();
    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(keyManagers, null, null);
    SSLContext.setDefault(sslContext);
  }

  public void testPlainJavaHTTPS() throws Exception {
    String httpsURL = "https://kaas-edge-admin.arm.com/api/v1/namespaces";
    URL myUrl = new URL(httpsURL);
    HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
    conn.setReadTimeout(3000);
        conn.setConnectTimeout(8 * 1000);
        conn.setRequestMethod("GET");

    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String text;
    StringBuilder result = new StringBuilder();
    while ((text = in.readLine()) != null)
      result.append(text);

    in.close();
  }

0 个答案:

没有答案