我需要使用智能卡登錄網站。我可以成功從智能卡獲取密鑰庫,其中包含用戶證書和不可導出私鑰(這是一個常規的PrivateKey對象,但「getEncoded」方法返回null)。Java中的客戶端證書認證
此網站:https://pst.giustizia.it/PST/authentication/it/pst_ar.wp 有一個登錄鏈接,這個鏈接更改您可以訪問。所以,就像用戶所做的那樣,我在我的Java應用程序中也這樣做:我訪問該頁面一次以獲取該鏈接,然後在該鏈接上執行SSL身份驗證(有點像模擬訪問頁面並單擊該鏈接) 。
這是我使用的代碼:
public class SSLAuth
{
private static String LOGIN_PAGE = "https://pst.giustizia.it/PST/authentication/it/pst_ar.wp";
private static String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0";
private TrustStrategy trustStrategy = new TrustStrategy()
{
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
{
// Temporary work-around. I already know how to fix this
return true;
}
};
public String authenticate(String pin) throws Exception
{
// Request KeyStore from smart card
KeyStore keyStore = Utility.digitalSigner.loadKeyStorePKCS11();
SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").loadTrustMaterial(keyStore, trustStrategy).build();
// Get login token first
String loginToken = null;
{
Document document = Jsoup.connect(LOGIN_PAGE).ignoreContentType(true).userAgent(USER_AGENT).timeout(10000).followRedirects(true).get();
Elements link = document.select("div > fieldset > p > a");
loginToken = link.get(0).attr("abs:href");
}
// Try to authenticate
HttpClient httpClient = HttpClients.custom().setUserAgent(USER_AGENT).setSSLContext(sslContext).build();
HttpResponse response = httpClient.execute(new HttpGet(loginToken));
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
return null;
return response.toString();
}
}
我只需要在第一時間進行身份驗證,因爲一旦登錄,網站只檢查一個名爲「JSESSIONID」 cookie和客戶端的用戶代理字符串。我已經測試過了。一旦你有了這兩個有效的參數,你甚至可以從另一個瀏覽器訪問該頁面。無論如何,「loadKeyStorePKCS11」方法爲您提供了上述密鑰庫,其中包含證書鏈(99%,也許100%只有一個證書,因爲我試過26個不同的智能卡,而且他們只有一個證書:用戶的)和一個不可導出的私鑰。 我試圖在互聯網上尋找解決方案,但它們都是關於PKCS#12的,我不需要它。
我試過使用不同的協議(SSL和TLS)和它的不同版本,但沒有任何!
Firefox可以做智能卡身份驗證,我知道我在程序中丟失了一些東西!當我在「httpClient」對象上調用「execute」方法時,它給了我一個例外:「handshake_failure」(SSLHandshakeException)。
如果我使用「loadKeyMaterial」而不是「loadTrustMaterial」,則會得到「unsupported_certificate」。
我真的不知道我在這一點上必須做什麼! 你有什麼建議嗎? 在此先感謝!
要查看失敗的原因,請將'-Djavax.net.debug = ssl:handshake'添加到您的JVM。我的猜測是不可信的根CA或密碼不匹配。 –
[這裏](https://www.dropbox.com/s/94m10zrfhpy4zmb/ConsoleMessage.txt?dl=0)可以找到整個控制檯日誌。前80行是來自智能卡驅動程序的調試消息。其餘的來自握手調試。提前致謝! – FonzTech
抱歉dropbox被我的代理服務器阻止。 –