Bonjour à tous,

Je me suis mis depuis peu à m'intéresser au package java.rmi

je souhaiterai faire communiquer un serveur et un/plusieurs client(s). Le tout me permettrai d'envoyer pour le moment une chaine de caractère.

Si je le fait sans passer par SSL, cela fonctionne très bien (du moins ça en à l'air ^^)

maintenant si je suis ici c'est qu'avec SSL cela pose problème.

Mon problème est que je génère sur mon client une exception :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Si je ne me trompe pas, cela signifie que le client et le server n'ont en gros, pas réussie a trouver un compromis pour échanger les donnée de manière sécurisé qui leurs conviennent.

Cela doit donc venir du certificat utilisé non ?

avant de continuer voici un peu de code

InterfaceServeur :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
import java.rmi.*;
public interface ServeurInterface extends Remote {
public void ecrirePassword(String password) throws RemoteException;
}
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
 
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
 
 
public class Serveur extends UnicastRemoteObject implements ServeurInterface{
 
	/**
         * 
         */
	private static final long serialVersionUID = -1217529625177961947L;
	public static int port;
	public static SslRMIClientSocketFactory csf;
	public static SslRMIServerSocketFactory ssf;
 
	public Serveur() throws RemoteException {}
 
	public Serveur(int port, SslRMIClientSocketFactory csf, SslRMIServerSocketFactory ssf) throws RemoteException{
		super(port,csf,ssf);
 
	}
 
	public void ecrirePassword(String password) throws RemoteException {
		System.out.println("le password est (Serveur) : "+ password);		
	}
 
	public static void main(String args[])
	{
 
		try
		{
			//set the security manager
			System.setSecurityManager(new RMISecurityManager());
 
			//Serveur server = new Serveur();
			port = 443;
			csf = new SslRMIClientSocketFactory();
			ssf = new SslRMIServerSocketFactory();
 
			Serveur server = new Serveur(port,csf,ssf);
			Naming.rebind("//mon-ip:1099/Serveur" , server);
			System.out.println("Server waiting on .....");
		}
		catch (RemoteException re)
		{
			System.out.println("Remote exception: " + re.toString());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
 
}
Classe Client :
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
 
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
 
 
public class Client {
 
	public Client() {}
 
	public static void main(String[] args)
	{
 
		//set the security manager for the client
		System.setSecurityManager(new RMISecurityManager());
		//get the remote object from the registry
		try
		{
			System.out.println("Security Manager loaded");
			String url = "//mon-ip:1099/Serveur";
			ServeurInterface _server = (ServeurInterface)Naming.lookup(url);
			System.out.println("Atteindre l'objet Remote");
 
			Tools t = new Tools();
			String password = t.generatePassword(10);
			System.out.println("test: ");
			_server.ecrirePassword(password);
			System.out.println("Insertion faite");
			System.out.println("Le password est : "+password);
		}
		catch (RemoteException exc)
		{
			System.out.println("Error in lookup: " + exc.toString());
			exc.printStackTrace();
		}
		catch (java.net.MalformedURLException exc)
		{
			System.out.println("Malformed URL: " + exc.toString());
		}
		catch (java.rmi.NotBoundException exc)
		{
			System.out.println("NotBound: " + exc.toString());
		}
		catch (Exception exc)
		{
			System.out.println("NotBound: " + exc.toString());
		}
	}
}
Je compile le tout puis en ligne de commande je fait ceci

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
//permet d'obtenir mon stub
rmic Serveur
 
//puis je lance le registre
rmiregistry
de plus j'ai un fichier policy de ce type pour accepter les connections
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
grant {
	permission java.net.SocketPermission "*:1024-65535", "accept, connect";
	permission java.net.SocketPermission "*:80", "connect";
	permission java.security.AllPermission "", "";
};
ensuite je lance mon serveur, puis mon client sans autre paramètre pour le moment.(le tout sur la même machine)

et la j'obtiens une levé d'exception au lancement du client :

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
 
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
	javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
	at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
	at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at Serveur_Stub.ecrirePassword(Unknown Source)
	at Client.main(Client.java:26)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
	at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
	at java.io.BufferedOutputStream.flush(Unknown Source)
	at java.io.DataOutputStream.flush(Unknown Source)
	... 5 more
j'ai tenté par la suite de créer un fichier keystore a l'aide de keytool :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
keytool -genkey -keystore myks -keyalg RSA
puis rajouter en paramètre au lancement de mon Serveur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
-Djavax.net.ssl.keyStore=myks -Djava.net.ssl.keyStorePassword=password
puis rajouter en paramètre au lancement de mon Client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
-Djavax.net.ssl.trustStore=myks -Djava.net.ssl.trsutStorePassword=password
mais cela me génère la même exception

De plus il me semblais que génère un certificat ssl avec keytool ne me servait pas en utilisant les classes "SslRMIClientSocketFactory" et "SslRMIServerSocketFactory" qui selons moi devaient se débrouiller toute seul avec les parametre par defaut ? (cf leur documentation respective)

SslRMIClientSocketFactory
SslRMIServerSocketFactory


Enfin voila, merci à ceux qui ont pris le temps de lire ce long post jusqu'au bout, j'ai déjà fait plusieurs recherches à ce sujet mais aucune des solution n'a résolu mon problème.

Quoi que je fasse, je me retrouve toujours avec la même levé d'exception. Du coup par SSL plus rien ne fonctionne.

ps : lorsque le code fonctionnait j'utilise le constructeur sans paramètre.