Test SSL connection
Problem
最近在評估某個功能整合時,剛好談到TLS。TLS1.0幾乎就是SSL 3.0;以java 8而言,預設已經使用TLS1.1或TLS1.2了。我好奇的是,HttpClient是否有做hostname的驗證。hostname驗證的目的是為了偵測連線是否被攻擊者導到它自己的機器上(MITM attack)。
Hot to?
我直接拿臉書URL做測試:
public static void main(String[] args) throws ClientProtocolException, IOException { HttpClient httpclient = null; try { httpclient = new DefaultHttpClient(); HttpGet get = new HttpGet("https://www.facebook.com/"); HttpResponse response = httpclient.execute(get); System.out.println(response.getStatusLine().getStatusCode()); } finally { HttpClientUtil.shutdownHttpClient(httpclient); } }正常來說,應該會拿到HTTP 200的Code。接著可以透過ping去取得domain name解析出來的IP,並將request位置改為IP:
HttpGet get = new HttpGet("https://31.13.95.36/");改完執行則會出現以下例外,也證明它是有做hostname的驗證的:
Exception in thread "main" javax.net.ssl.SSLException: hostname in certificate didn't match: <31.13.95.36> != <*.facebook.com> at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:228) at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148) at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) at org.tonylin.stock.dao.DatabaseStockDaoTest.main(DatabaseStockDaoTest.java:56)