Identification d'un client Java via un certificat SSL

Pour continuer l’article précédent intitulé « Identification Firefox via un certificat SSL« , vous trouverez ci-dessous comment utiliser un certificat SSL avec un client Java. Pour ce faire, il faut que les mêmes conditions soient réunies que dans l’article précédent à savoir :

Une fois la configuration serveur réalisée, vous pouvez vous lancer dans la configuration et l’utilisation d’un client…

Certificat et KeyStore client

Dans une première étape, vous allez générer un keystore et un certificat pour votre client et demander une signature par l’autorité de certification. Dans notre exemple, nous avons utilisé changeit comme mot de passe du store et de la clé :

$ keytool -genkeypair -dname "cn=agent1, o=arkzoyd, c=FR" 
-alias agent -keystore keystore.jks
Enter keystore password:
Re-enter new password:
Enter key password for <agent>
    (RETURN if same as keystore password):  


$ keytool -certreq -alias agent  -keystore keystore.jks -file agent.csr
Enter keystore password: 

$ cp agent.csr ~/CA/newreq.pem

$ cd ~/CA

$ /usr/lib/ssl/misc/CA.pl -sign
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            b4:1d:38:bd:49:9c:6c:48
        Validity
            Not Before: Dec  6 08:30:34 2010 GMT
            Not After : Dec  6 08:30:34 2011 GMT
        Subject:
            countryName               = FR
            organizationName          = arkzoyd
            commonName                = agent1
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                BF:EF:A1:BC:63:67:CE:B1:A1:81:DF:6C:3D:E5:AB:8E:DF:F7:CA:36
            X509v3 Authority Key Identifier:
                keyid:E0:FB:6B:4C:38:31:CA:A3:67:2C:82:28:86:A7:A9:E8:96:6A:AD:22

Certificate is to be certified until Dec  6 08:30:34 2011 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem


$ cd -

$ cp ~/CA/newcert.pem agent.pem

Enregistrez ensuite le certificat de l’autorité de certification comme

trustedCertEntry

dans votre keystore :

$ keytool -importcert -alias ca -file ~/CA/demoCA/cacert.pem -keystore keystore.jks
Enter keystore password: 
Owner: CN=CA, O=ArKZoYd, ST=Paris, C=FR
Issuer: CN=CA, O=ArKZoYd, ST=Paris, C=FR
Serial number: b41d38bd499c6c41
Valid from: Sat Dec 04 19:09:39 CET 2010 until: Tue Dec 03 19:09:39 CET 2013
Certificate fingerprints:
     MD5:  B3:59:FE:AF:B6:DF:42:8F:B5:8A:08:1E:44:AE:15:ED
     SHA1: 72:07:A2:8A:EF:D4:7B:6B:A3:AF:05:91:04:92:3B:E5:E4:AF:99:16
     Signature algorithm name: SHA1withRSA
     Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E0 FB 6B 4C 38 31 CA A3   67 2C 82 28 86 A7 A9 E8  ..kL81..g,.(....
0010: 96 6A AD 22                                        .j."
]
]

#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: E0 FB 6B 4C 38 31 CA A3   67 2C 82 28 86 A7 A9 E8  ..kL81..g,.(....
0010: 96 6A AD 22                                        .j."
]

[CN=CA, O=ArKZoYd, ST=Paris, C=FR]
SerialNumber: [    b41d38bd 499c6c41]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

Editer ensuite le fichier agent.pem de votre certificat signé et supprimez toutes les lignes avant la section -----BEGIN CERTIFICATE----- :

$ vi agent.pem 

Enfin chargez le certificat signé dans le keystore :

$ keytool -importcert -alias agent -file agent.pem -keystore keystore.jks
Enter keystore password: 
Certificate reply was installed in keystore


$ keytool -list  -keystore keystore.jks
Enter keystore password: 

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

ca, Dec 6, 2010, trustedCertEntry,
Certificate fingerprint (MD5): B3:59:FE:AF:B6:DF:42:8F:B5:8A:08:1E:44:AE:15:ED
agent, Dec 6, 2010, PrivateKeyEntry,
Certificate fingerprint (MD5): C1:8C:F1:77:01:9B:4D:7A:72:8B:D8:24:B5:90:DD:E5

Développer votre client Java

Vous voici prêt à développer et configurer votre client Java ; Voici le code associé ainsi que l’ensemble des paramètres associés tels que les keystore, mots de passe et URL de connexion au serveur :

package com.arkzoyd;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

/**
* @author arkzoyd
*
*/
public class Query {

/**
* @param args
*/
public static void main(S tring[] args) {
// Settings
String s_url = "https://red.easyteam.fr:8181/demo/faces/index.xhtml";
System.setProperty("javax.net.ssl.keyStoreType","JKS");
System.setProperty("javax.net.ssl.keyStore","keys/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword","changeit");

System.setProperty("javax.net.ssl.trustStoreType","JKS");
System.setProperty("javax.net.ssl.trustStore","keys/keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");
//System.setProperty("javax.net.debug","ssl");

try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL(s_url);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println("Received " + string);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Il ne reste plus qu’à tester votre application et valider qu’avec le certificat client, celle-ci fonctionne correctement alors que sans ou après l’avoir révoqué sur le serveur, il est impossible d’accéder à la ressource correspondante…