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 :
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Cela doit donc venir du certificat utilisé non ?
avant de continuer voici un peu de code
InterfaceServeur :
Classe Serveur :
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 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
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(); } } }
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
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()); } } }
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 //permet d'obtenir mon stub rmic Serveur //puis je lance le registre rmiregistry
ensuite je lance mon serveur, puis mon client sans autre paramètre pour le moment.(le tout sur la même machine)
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 "", ""; };
et la j'obtiens une levé d'exception au lancement du client :
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
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
puis rajouter en paramètre au lancement de mon Serveur :
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 Client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 -Djavax.net.ssl.keyStore=myks -Djava.net.ssl.keyStorePassword=password
mais cela me génère la même exception
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 -Djavax.net.ssl.trustStore=myks -Djava.net.ssl.trsutStorePassword=password
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.
Partager