スマートカードを使用してウェブサイトにログインする必要があります。ユーザーの証明書と非エクスポート可能な秘密鍵(通常の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とクライアントのユーザーエージェント文字列をログインしたので、私は、最初の時間を認証するだけで済みます。私はすでにこれをテストしました。これら2つの有効なパラメータがあれば、別のブラウザからでもこのページにアクセスできます。
"loadKeyStorePKCS11"メソッドは、認証チェーン(99%、多分100%は1つの証明書だけです)を含む上記のキーストアを提供します。26種類のスマートカードを試したので、ユーザのもの)と、エクスポート不可能な秘密鍵とを含む。 私は解決策についてインターネットを見ようとしましたが、PKCS#12についてはすべてですが、これは必要ありません。
私は別のプロトコル(SSLとTLS)とそれの異なるバージョンを使用しようとしましたが、何もしませんでした!
Firefoxはスマートカード認証を行うことができますが、手順で何か不足していることがわかりました。 "httpClient"オブジェクトの "execute"メソッドを呼び出すと、 "handshake_failure"(SSLHandshakeException)例外が発生します。
「loadTrustMaterial」の代わりに「loadKeyMaterial」を使用すると、「unsupported_certificate」が取得されます。
私はこの時点で何をすべきか分かりません。 アドバイスをお持ちですか? ありがとうございます!
エラーの理由を確認するには、 '-Djavax.net.debug = ssl:handshake'をJVMに追加します。私の推測は、信頼できないルートCAまたは暗号不一致です。 –
[こちら](https://www.dropbox.com/s/94m10zrfhpy4zmb/ConsoleMessage.txt?dl=0)コンソールログ全体を見つけることができます。最初の80行は、スマートカードドライバからのデバッグメッセージです。残りはハンドシェイクデバッグからのものです。前もって感謝します! – FonzTech
残念ながら、Dropboxはプロキシサーバーによってブロックされています。 –