Test SSL connection

最近在評估某個功能整合時,剛好談到TLS。TLS1.0幾乎就是SSL 3.0;以java 8而言,預設已經使用TLS1.1或TLS1.2了。我好奇的是,HttpClient是否有做hostname的驗證。hostname驗證的目的是為了偵測連線是否被攻擊者導到它自己的機器上(MITM attack)。

我直接拿臉書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)