[JAVA] SSL handshake連線測試工具 SSLPoke

這邊就用 www.google.com 測試.
簡單做個筆記.

有時候SSL連線不順, 有錯誤訊息如下, 

Error rendering macro: java.io.IOException: Could not download: https://siteURL/jira/secure/IssueNavigator.jspa?view=rss&&type=12&type=4&type=3&pid=10081&resolution=1&fixfor=10348&sorter/field=issuekey&sorter/order=DESC&sorter/field=priority&sorter/order=DESC&tempMax=100&reset=true&decorator=none
...
...
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
...

可以考慮用Atlassian介紹的SSLPoke 進行測試.
https://confluence.atlassian.com/kb/unable-to-connect-to-ssl-services-due-to-pkix-path-building-failed-779355358.html

他的程式碼如下.

import java.io.PrintStream;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class SSLPoke
{
  public SSLPoke() {}
  
  public static void main(String[] paramArrayOfString)
  {
    if (paramArrayOfString.length != 2) {
      System.err.println("Utility to debug Java connections to SSL servers");
      System.err.println("Usage: ");
      System.err.println("  java " + SSLPoke.class.getName() + " <host> <port>");
      System.err.println("or for more debugging:");
      System.err.println("  java -Djavax.net.debug=ssl " + SSLPoke.class.getName() + " <host> <port>");
      System.err.println();
      System.err.println("Eg. to test the SSL certificate at https://localhost, use");
      System.err.println("  java " + SSLPoke.class.getName() + " localhost 443");
      System.exit(1);
    }
    try {
      SSLSocketFactory localSSLSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
      SSLSocket localSSLSocket = (SSLSocket)localSSLSocketFactory.createSocket(paramArrayOfString[0], Integer.parseInt(paramArrayOfString[1]));
      
      java.io.InputStream localInputStream = localSSLSocket.getInputStream();
      java.io.OutputStream localOutputStream = localSSLSocket.getOutputStream();
      

      localOutputStream.write(1);
      
      while (localInputStream.available() > 0) {
        System.out.print(localInputStream.read());
      }
      System.out.println("Successfully connected");
      System.exit(0);
    }
    catch (SSLHandshakeException localSSLHandshakeException) {
      if (localSSLHandshakeException.getCause() != null) {
        localSSLHandshakeException.getCause().printStackTrace();
      } else {
        localSSLHandshakeException.printStackTrace();
      }
    } catch (Exception localException) {
      localException.printStackTrace();
    }
    System.exit(1);
  }
}

執行測試結果如下:

## 先打包成class
$ javac SSLPoke.java
$ java SSLPoke www.google.com 443

連線成功會顯示

$ java SSLPoke www.google.com 443
Successfully connected

失敗會顯示

$ java SSLPoke www.google.com 443
java.net.ConnectException: Connection refused (Connection refused)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673)
        at sun.security.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:432)
        at sun.security.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:88)
        at SSLPoke.main(SSLPoke.java:25)

後者可能要檢查一下是不是網路哪邊被擋了.