Bonjour à tous,

Comme vous pouvez vous en douter avec le titre du topique, je fais face à un problème que je ne parviens pas à résoudre.

En suivant un mini-tuto, j'ai voulu adapter un mini-chat pour utiliser des sockets sécurisés.

Mais lorsque je souhaite lancer le serveur, il me met la trace d'erreur suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
java.security.UnrecoverableKeyException: Cannot recover key
	at sun.security.provider.KeyProtector.recover(Unknown Source)
	at sun.security.provider.JavaKeyStore.engineGetKey(Unknown Source)
	at sun.security.provider.JavaKeyStore$JKS.engineGetKey(Unknown Source)
	at sun.security.provider.KeyStoreDelegator.engineGetKey(Unknown Source)
	at sun.security.provider.JavaKeyStore$DualFormatJKS.engineGetKey(Unknown Source)
	at java.security.KeyStore.getKey(Unknown Source)
	at sun.security.ssl.SunX509KeyManagerImpl.<init>(Unknown Source)
	at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(Unknown Source)
	at javax.net.ssl.KeyManagerFactory.init(Unknown Source)
	at server.ServerUtils.km(ServerUtils.java:48)
	at server.ServerUtils.getServerSocketWithCert(ServerUtils.java:77)
	at server.Serveur.<init>(Serveur.java:23)
	at server.Serveur.main(Serveur.java:38)
Voici le code de la classe Serveur :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package server;
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
 
import javax.net.ssl.SSLServerSocket;
 
public class Serveur {
 //public static ServerSocket ss = null;
 public static SSLServerSocket ss = null;
 public static Thread t;
 public static int port = 2009;
 
 	private Serveur() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, KeyStoreException {
 
 		try {
			//ss = new ServerSocket(2009);
			//
			System.out.println("Le serveur est à l'écoute du port "+ss.getLocalPort());
 
			t = new Thread(new Accepter_connexion(ss));
			t.start();
 
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("Le port "+ss.getLocalPort()+" est déjà utilisé !");
		}
 	}
 
	public static void main(String[] args) {
 
		try {
			Serveur serveur = new Serveur();
		} catch (KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | CertificateException
				| KeyStoreException e) {
			e.printStackTrace();
		}
 
	}	
}
Puis le code de la classe ServerUtils :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package server;
 
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
 
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
 
public class ServerUtils {
	/**
         * Ca c'est une fonction utilitaire permettant de récupérer le "vérifieur de certificat", on prend uniquement celui correspondant au certificat pour minimiser le temps de chargement à la connexion
         * 
         * Pas très intéressante...
         */
	private static X509TrustManager tm(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
		TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustMgrFactory.init(keystore);
        //on prend tous les managers
        TrustManager trustManagers[] = trustMgrFactory.getTrustManagers();
        for (int i = 0; i < trustManagers.length; i++) {
            if (trustManagers[i] instanceof X509TrustManager) {
                //on renvoie juste celui que l'on va utiliser
                return (X509TrustManager) trustManagers[i];
            }
        }
        return null;
    };
    /**
     * Ca c'est une fonction utilitaire permettant de récupérer le "gestionnaire de mot de passes des clés" (en gros)
     * 
     * Pas très intéressante...
     */
    private static X509KeyManager km(KeyStore keystore, String password) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
		KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyMgrFactory.init(keystore, password.toCharArray());
        //on prend tous les managers
        KeyManager keyManagers[] = keyMgrFactory.getKeyManagers();
        for (int i = 0; i < keyManagers.length; i++) {
            if (keyManagers[i] instanceof X509KeyManager) {
                //on renvoie juste celui que l'on va utiliser
                return (X509KeyManager) keyManagers[i];
            }
        }
        return null;
    };
 
 
 
    /**
     * Le vrai morceau, que l'on utilisera
     */
    public static SSLServerSocket getServerSocketWithCert(int port, InputStream pathToCert, String passwordFromCert) throws IOException,
									KeyManagementException, NoSuchAlgorithmException, CertificateException, KeyStoreException, UnrecoverableKeyException{
		TrustManager[] tmm = new TrustManager[1];
		KeyManager[] kmm = new KeyManager[1];
		//On charge le lecteur de Keystore en fonction du format
		//ATTENTION
		//POUR LES SERVEURS android, remplacez le JKS par BKS, si c'est juste le client qui est android, laissez JKS
		KeyStore ks  = KeyStore.getInstance("JKS");
		//On charge le Keystore avec sont stream et son mot de passe
		ks.load(pathToCert, passwordFromCert.toCharArray());
		//On lance les gestionnaires de clés et de vérification des clients
		tmm[0]=tm(ks);
		kmm[0]=km(ks, passwordFromCert);
		//On démarre le contexte, autrement dit le langage utilisé pour crypter les données
		//ATTENTION
		//Ici, on peut remplacer SSL par TLSv1.2 , mais il faudra le faire aussi bien dans le client que le serveur
		SSLContext ctx = SSLContext.getInstance("TLSv1.2");
		ctx.init(kmm, tmm, null);
		//On lance la serversocket sur le port indiqué, avec le contexte fourni
		SSLServerSocketFactory socketFactory = (SSLServerSocketFactory) ctx.getServerSocketFactory();
		return (SSLServerSocket) socketFactory.createServerSocket(port);
	}
}
Quelqu'un a-t-il une solution ?

Merci