2011-12-17 47 views
6

有誰知道在Java中編寫SSL檢查器有什麼好的教程,站點和書嗎?我正在嘗試做什麼可以在這裏找到:http://www.sslshopper.com/ssl-checker.html。 我不想創建自簽名證書或使用密鑰庫。我希望能夠到任何網站確定是否存在有效的SSL證書,確定證書上的主機名是否與指定的輸入相匹配,並確定此證書何時過期。我已經搜索了這個主題,但「如何創建一個使用Java的SSL購物者」並沒有讓我失去任何東西,我的其他搜索只給我提供了關於如何創建一個自簽名證書的鏈接。任何幫助將不勝感激。使用Java編寫SSL檢查器

回答

1

你可以做的是落實的e.g頂部Apache's HttpClient
你應該初始化SSL上下文和覆蓋TrustManagers做任何檢查你想你自己的檢查。

主機名驗證可以由庫自動完成。

例如下面將配置SSL套接字操作拋出一個異常,如果主機名不匹配的證書的信息:

SSLSocketFactory sf = new SSLSocketFactory(
    SSLContext.getInstance("TLS"), 
    SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); 
3

要獲得以做手工驗證在首位的服務器證書,而不管其是否是有效或無效,最簡單的方法是在禁用任何證書驗證後通過SSLSocket進行連接。

創建SSLContext,通過讓任何東西:

SSLContext sslContext = SSLContext.getInstance("TLS"); 
X509TrustManager passthroughTrustManager = new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    } 
}; 
sslContext.init(null, new TrustManager[] { passthroughTrustManager }, 
     null); 

(旁註:爲人們尋找一種方式在內部使用測試證書,我建議建立自己的試驗Ca,而不是禁用的檢查,只是如果這些虛擬檢查被錯誤地留在生產代碼中,並且也因爲它使得測試更現實)。

創建一個套接字,明確地連接並啓動握手(因爲你不會真正閱讀表單它):

SSLSocketFactory ssf = sslContext.getSocketFactory(); 
SSLSocket socket = (SSLSocket) ssf.createSocket(
     "the.host.name", 443); 
socket.startHandshake(); 

獲取對等證書鏈。第一項是實際的服務器證書。

X509Certificate[] peerCertificates = (X509Certificate[]) socket 
     .getSession().getPeerCertificates(); 

如果你想驗證對默認信任錨(默認可信CA證書),基於默認值建立一個X509TrustManager(這實際上是什麼上述禁用passthroughTrustManager):

// By default on Oracle JRE, algorithm is PKIX 
TrustManagerFactory tmf = TrustManagerFactory 
     .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
// 'null' will initialise the tmf with the default CA certs installed 
// with the JRE. 
tmf.init((KeyStore) null); 
X509TrustManager tm = (X509TrustManager) tmf.getTrustManagers()[0]; 

現在,檢查證書是否當前有效,是否對可信錨點進行驗證,以及它是否具有根據RFC 3280的正確擴展名。

try { 
    // Assuming RSA key here. 
    tm.checkServerTrusted(peerCertificates, "RSA"); 
} catch (CertificateException e) { 
    // Here you may check which subclass of CertificateException to know what the error is. 
} 

以上所有都使用JSSE API

或者,如果您想深入瞭解PKIX的詳細信息,可以使用Java Certification Path API(由JSSE使用)。

(如果您只想要開始使用有效證書,只需在開始時使用SSLContext sslContext = SSLContext.getDefault(),創建套接字並執行握手。)

要直接獲得服務器證書,您可以使用此:

X509Certificate serverCert = peerCertificates[0]; 

X509Certificate有關於日期和各種擴展的一些方法。例如:

Date expirationDate = serverCert.getNotAfter(); 

的主機名驗證應遵循RFC 6125(或至少RFC 2818)。簡而言之,請檢查您要連接的主機名是否是主題備用名稱(SAN)DNS條目之一。如果不這樣做,請重新檢查主機名是否位於證書的CN RDN中(爲此,您需要將主題DN分割爲RDN)。您可能也有興趣this discussion (on the specific case of using IP addresses)

這一切都取決於您要做多少「手動」驗證。除了API文檔之外,還有許多規範可以閱讀(至少是RFC 5280/RFC 3280和RFC 6125/RFC 2818)。

上Security.SE這個問題也應該有興趣:

+0

我想這樣做時,你得到不可轉換類型:X509證書[] peerCertificates =(X509證書[ ])socket.getSession()getPeerCertificates(); – W3B5T4R 2011-12-17 19:37:37

+0

我甚至嘗試使用上面的Oracles的網站的例子,並不斷得到「不可兌換的類型」 – W3B5T4R 2011-12-17 20:06:38

+0

沒關係,我看到,我正在使用導入javax.security.cert.X509Certificate;而不是import java.security.cert.X509Certificate; – W3B5T4R 2011-12-17 21:33:05