Je dois me connecter à un site Web à l'aide d'une carte à puce. Je peux obtenir avec succès le keystore de la carte à puce, contenant le certificat de l'utilisateur et une clé privée non exportable (c'est un objet PrivateKey classique, mais la méthode "getEncoded" renvoie null).Authentification du certificat client en Java
Ce site: https://pst.giustizia.it/PST/authentication/it/pst_ar.wp a un lien de connexion qui change chaque fois que vous visitez. Donc, comme le ferait un utilisateur, je fais de même dans mon application Java: je consulte la page une fois pour obtenir ce lien, puis j'effectue l'authentification SSL sur ce lien (Un peu comme simuler la visite de la page et cliquer sur ce lien) .
C'est le code que j'utilise:
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();
}
}
J'ai besoin que d'authentifier la première fois, car une fois connecté, les contrôles du site qu'un cookie nommé « JSESSIONID » et la chaîne de l'agent utilisateur du client. J'ai déjà testé ça. Une fois que vous avez ces deux paramètres valides, vous pouvez visiter la page même à partir d'un autre navigateur. Quoi qu'il en soit, la méthode "loadKeyStorePKCS11" vous donne le keystore mentionné ci-dessus, qui contient la chaîne de certification (99%, peut-être 100% sont un seul certificat, car j'ai essayé 26 cartes à puce différentes et un seul certificat: celui de l'utilisateur), et une clé privée non exportable. J'ai essayé de trouver des solutions sur Internet, mais elles concernent toutes le PKCS # 12, dont je n'ai pas besoin.
J'ai essayé d'utiliser différents protocoles (SSL et TLS) et différentes versions, mais rien!
Firefox peut faire l'authentification par carte à puce, et je sais qu'il me manque quelque chose dans la procédure! Lorsque j'appelle la méthode "execute" sur l'objet "httpClient", cela me donne une exception: "handshake_failure" (SSLHandshakeException).
Si j'utilise "loadKeyMaterial" au lieu de "loadTrustMaterial", j'obtiens "unsupported_certificate".
Je ne sais pas vraiment ce que je dois faire à ce stade! Avez-vous un conseil? Merci d'avance!
pour voir la raison de l'échec, ajoutez '-Djavax.net.debug = ssl: handshake' à votre machine virtuelle Java. Ma conjecture est une autorité de certification racine non fiable ou une incompatibilité de chiffrement. –
[ICI] (https://www.dropbox.com/s/94m10zrfhpy4zmb/ConsoleMessage.txt?dl=0) vous pouvez trouver l'intégralité du journal de la console. Les 80 premières lignes sont des messages de débogage du pilote de la carte à puce. Le reste provient du débogage de la poignée de main. Merci d'avance! – FonzTech
Désolé, la boîte de dépôt est bloquée par mon serveur proxy. –