Java SSL socket, klietn a server – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Java SSL socket, klietn a server – Java – Fórum – Programujte.comJava SSL socket, klietn a server – Java – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
martin
~ Anonymní uživatel
1377 příspěvků
29. 9. 2012   #1
-
0
-

Zdravim, komunikace pres socket mi uz funguje, ale nyni potrebuji SSL.

Upravil jsem nasledovne kod:

Server:

StartServer.java:

package server;
import java.io.IOException;

public class StartServer {
	public static void main(String[] args) throws IOException {
		SitServer s = new SitServer("127.0.0.1", 4444);
		s.handleConnection();
	}
}

SitServer.java:

package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ClassNotFoundException;
import java.lang.Runnable;
import java.lang.Thread;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
 
public class SitServer {
	// http://www.kodejava.org/…les/216.html
	private String host;
	private int port;	
	private ServerSocket server;
	private ServerSocket ssocket;

	public SitServer(String host, int port) throws IOException {
		this.host = host;
		this.port = port;
		// http://www.exampledepot.com/…/Server.html
		ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
	    ssocket = ssocketFactory.createServerSocket(port);
	}

    public void handleConnection() {
        System.out.println("Waiting for client message...");
 
        while (true) {
            try {
            	Socket socket = ssocket.accept();
                new ConnectionHandler(socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    public String getHost() {
		return host;
	}
    
    public void setHost(String host) {
		this.host = host;
	}
    
    public int getPort() {
		return port;
	}
    
    public void setPort(int port) {
		this.port = port;
	}
    
}
 
class ConnectionHandler implements Runnable {
    private Socket socket;
 
    public ConnectionHandler(Socket socket) {
        this.socket = socket;
 
        Thread t = new Thread(this);
        t.start();
    }
 
    public void run() {
        try
        {
            // Read a message sent by client application
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            String message = (String) ois.readObject();
            
            
            // Send a response information to the client application
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
          
            if (message.equals("ABC")) {
            	System.out.println("Message Received: ABC " + message);
            	oos.writeObject("Prijato: " + message + "\n");
			} else if (message.equals("DEF")) {
				System.out.println("Message Received: DEF " + message);
				oos.writeObject("Prijato: " + message + "\n");
			} else {
				System.out.println("Message Received: JINE... "+  message);
				oos.writeObject("Prijato: " + message + "\n");
			}
 
            ois.close();
            oos.close();
            socket.close();
 
            System.out.println("Waiting for client message...");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Klient

StartKlient.java:

package klient;

import java.io.IOException;
import java.net.UnknownHostException;

public class StartKlient {

	public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
		SitKlient sk = new SitKlient("127.0.0.1", 4444);
		sk.SocketWrite("ABC");
		System.out.println(sk.SocketRead());		
	}
}

SitKlient.java:

package klient;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ClassNotFoundException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
 
public class SitKlient {	
	private Socket klient;
	
	public SitKlient(String host, int port) throws UnknownHostException, IOException {
		SocketFactory socketFactory = SSLSocketFactory.getDefault();
	    Socket klient = socketFactory.createSocket(host, port);
	}
	
	public void SocketWrite(String text) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(klient.getOutputStream());
        oos.writeObject(text);
        oos.flush();
	}
	
	public String SocketRead() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(klient.getInputStream());
        String message = (String) ois.readObject();
        return message;
	}

	public void SocketZavrit() throws IOException {
		klient.close();
	}
}

Hned pri spusteni serveru to spadne s: 

Exception in thread "main" java.net.BindException: Address already in use
	at java.net.PlainSocketImpl.socketBind(Native Method)
	at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
	at java.net.ServerSocket.bind(ServerSocket.java:328)
	at java.net.ServerSocket.<init>(ServerSocket.java:194)
	at java.net.ServerSocket.<init>(ServerSocket.java:150)
	at javax.net.ssl.SSLServerSocket.<init>(SSLServerSocket.java:84)
	at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.<init>(SSLServerSocketImpl.java:81)
	at com.sun.net.ssl.internal.ssl.SSLServerSocketFactoryImpl.createServerSocket(SSLServerSocketFactoryImpl.java:58)
	at server.SitServer.<init>(SitServer.java:26)
	at server.StartServer.main(StartServer.java:6)

Kde delam chybu?

Nahlásit jako SPAM
IP: 93.89.146.–
Reklama
Reklama
Dano
~ Anonymní uživatel
100 příspěvků
29. 9. 2012   #2
-
0
-

Nemas nahodou 2x pusteny server?

Nahlásit jako SPAM
IP: 91.127.65.–
martin
~ Anonymní uživatel
1377 příspěvků
30. 9. 2012   #3
-
0
-

#2 Dano
V Eclipse spustim program jen jednou a hned to dela tento problem :-(

Nahlásit jako SPAM
IP: 93.89.146.–
liborb
~ Redaktor
+18
Guru
1. 10. 2012   #4
-
0
-

No a nemáš puštěný ten bez SSL? Používáš stejný port (4444), tak zkus jiný ...

Nahlásit jako SPAM
IP: 78.80.52.–
Dano
~ Anonymní uživatel
100 příspěvků
1. 10. 2012   #5
-
0
-

Otazka na uvod ;) Preco chces pouzit SSLServerSocketFactory? Pri obycajnej komunikacii staci ServerSocketFactory.

Ked uz chces pouzit SSLServerSocketFactory, musis mu povedat, kde ma certifikaty, bez toho sa ssl nespusti. Pozri napriklad http://www.exampledepot.com/egs/javax.net.ssl/server.html

Nahlásit jako SPAM
IP: 195.28.127.–
martin
~ Anonymní uživatel
1377 příspěvků
2. 10. 2012   #6
-
0
-

#5 Dano
Ja jsem ani nevedel, ze exituje ServerSocketFactory a SSLServerSocketFactory.

Tomu ServerSocketFactory certifikaty predavat nemusim?

Musi to byt pomoci "java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer"?

Staci to jen na serveru?

Rad bych si poridil certifikat od duveryodne CA (treba VeriSign, nebo StartSSL) a pouzil ho na serveru, klient by se pak uz jen pripojil a zadne certifikaty by nemusel resit. Je to mozne? Co musim pouzit ServerSocketFactory, nebo SSLServerSocketFactory?

Diky za pomoc :-)

Nahlásit jako SPAM
IP: 195.113.118.–
Dano
~ Anonymní uživatel
100 příspěvků
2. 10. 2012   #7
-
0
-

#6 martin
Tomu ServerSocketFactory certifikaty predavat nemusim?

+ Nie nemusis, vytvori klasicky http:// protocol. SSLServerSocketFactory sa pouziva, ked chces komunikovat zabezpecene cez https://

Musi to byt pomoci "java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer"?

+ na toto Ti asi neodpoviem presne, nikdy som nepotreboval spustat aplikaciu s obdobnymi nastaveniami, no myslim si, ze ked nahras certifikaty na server (tomacat, glassfish, ...) tak by sa k nim malo vediet pristupovat. Ked si vytvaras ssl server sam, Tvoj pripad, tak mu musis povedat, kde ich mas ulozene, no aj tak si myslim, ze popisovane properties vies nastavit priamo v kode.

Staci to jen na serveru?

+ myslim si, ze ano.

Rad bych si poridil certifikat od duveryodne CA (treba VeriSign, nebo StartSSL) a pouzil ho na serveru, klient by se pak uz jen pripojil a zadne certifikaty by nemusel resit. Je to mozne?

+ klient nemusi certifikaty riesit napriamo, nepotrebuje ich poznat pred tym, ako sa pripoji na server, ked zagooglis urcite najdes navod pre tvorbu ssl socket self signed certificate client-a ;)

Co musim pouzit ServerSocketFactory, nebo SSLServerSocketFactory?

+ podla toho ci chces nezabezpecenu alebo zabezpecenu komunikaciu klient <-> server.

Nahlásit jako SPAM
IP: 195.28.127.–
martin
~ Anonymní uživatel
1377 příspěvků
2. 10. 2012   #8
-
0
-

#7 Dano
Dekuji za rady.

Zkusim pouzit SSLServerSocketFactory, potrebuji totiz sifrovane spojeni.

Ne nesifrovane spojeni mi stacilo

import java.net.ServerSocket;

server = new ServerSocket(port);

Je nejaky rozdil mezi ServerSocketFactory a ServerSocket?

Nahlásit jako SPAM
IP: 93.89.146.–
martin
~ Anonymní uživatel
1377 příspěvků
3. 10. 2012   #9
-
0
-

#8 martin
Tak jsem postupoval podle navodu: http://ruchirawageesha.blogspot.cz/2010/07/how-to-create-clientserver-keystores.html :

keytool -genkey -alias server -keyalg RSA -keystore server.jks
keytool -genkey -alias client -keyalg RSA -keystore client.jks
keytool -list -v -keystore server.jks
keytool -list -v -keystore server.jks -storepass pokus123
keytool -export -file server.cert -keystore server.jks -storepass pokus123 -alias server
keytool -export -file client.cert -keystore client.jks -storepass pokus123 -alias client
keytool -printcert -v -file server.cert
keytool -printcert -v -file client.cert
keytool -import -file client.cert -keystore server.jks -storepass pokus123 -alias client
keytool -import -file server.cert -keystore client.jks -storepass pokus123 -alias server
keytool -list -v -keystore server.jks -storepass pokus123
keytool -list -v -keystore client.jks -storepass pokus123

Kod jsem upravil:

SERVER: 

package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ssl.SSLServerSocketFactory;
 
public class SitServer {
	private int port;	
	private ServerSocket sslserver;

	public SitServer(int port) throws IOException {
		this.port = port;
		
		System.setProperty("javax.net.ssl.keyStore", "server.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "pokus123");
        SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        sslserver = ssf.createServerSocket(port);	
	}

    public void handleConnection() {
        System.out.println("Waiting for client message...");
        while (true) {
            try {
            	Socket socket = sslserver.accept();
                //Socket socket = sslserver.accept();
                new ConnectionHandler(socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public int getPort() {
		return port;
	}
    
    public void setPort(int port) {
		this.port = port;
	}
    
}
 
class ConnectionHandler implements Runnable {
    private Socket socket;
 
    public ConnectionHandler(Socket socket) {
        this.socket = socket;
 
        Thread t = new Thread(this);
        t.start();
    }
 
    public void run() {
        try
        {
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            String message = (String) ois.readObject();
            
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
          
            if (message.equals("ABC")) {
            	System.out.println("Message Received: ABC " + message);
            	oos.writeObject("Prijato: " + message + "\n");
			} else if (message.equals("DEF")) {
				System.out.println("Message Received: DEF " + message);
				oos.writeObject("Prijato: " + message + "\n");
			} else {
				System.out.println("Message Received: JINE... "+  message);
				oos.writeObject("Prijato: " + message + "\n");
			} 
            ois.close();
            oos.close();
            socket.close();
 
            System.out.println("Waiting for client message...");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

KLIENT: 

package klient;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLSocketFactory;
 
public class SitKlient {	
	private Socket klient;
	
	public SitKlient(String host, int port) throws UnknownHostException, IOException {
		System.setProperty("javax.net.ssl.keyStore", "client.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "pokus123");
		SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
	    klient = socketFactory.createSocket(host, port);	
	}
	
	public void SocketWrite(String text) throws IOException {		
        ObjectOutputStream oos = new ObjectOutputStream(klient.getOutputStream());
        oos.writeObject(text);
        oos.flush();
	}
	
	public String SocketRead() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(klient.getInputStream());
        String message = (String) ois.readObject();
        return message;
	}

	public void SocketZavrit() throws IOException {
		klient.close();
	}
}	

Server se spusti bez problemu, ale klient zhavaruje:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
	at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
	at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
	at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:230)
	at klient.SitKlient.SocketWrite(SitKlient.java:27)
	at klient.StartKlient.main(StartKlient.java:10)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
	at sun.security.validator.Validator.validate(Validator.java:218)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
	... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
	... 18 more

Kde delam tentokrat chybu? 

Jde nejak udelat keyStore na serveru s certifikatem serveru a jeho soukromym klicem bez nutnosti vkladat klientske certifikaty? A na klientu mit keyStore pouze s verejnym certifikatem serveru - tedy zadny klic a certifikat klienta. Je to mozne?

Nahlásit jako SPAM
IP: 93.89.146.–
Dano
~ Anonymní uživatel
100 příspěvků
4. 10. 2012   #10
-
0
-

Problem Tvojej exception je krasne popisany na http://code.naishe.in/2011/07/looks-like-article-no-more-unable-to.html

K Tvojej otazke co sa tyka klienta, nie je treba ukladat na server jeho certifikaty, ako aj ukladat server certifikaty na klienta. Ako je popisane vo vyssie uvedenej linke, ked sa client prihlasi na server, server vie clientovi poslat vsetky potrebne certifikaty, ktore si client ulozi. Parovanie server -> certifikat sa v tomto pripade robi cez prikaz  

ks.setCertificateEntry(alias, cert);

Takze keby si chcel napisat univerzalneho klienta, tak pri prihlaseni na server si overis co na dany server mas ulozene certifikaty, ak ano, pokracujes v pripojeni, ak nie, vypytas si ich od servera, ulozis a nasledne sa pripojis.

Nahlásit jako SPAM
IP: 195.28.127.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 31 hostů

Podobná vlákna

TCP Socket Server Java — založil wiston

Java client server — založil Falcon1651

JAVA UDP server — založil Lolek

Java klient + C server — založil Dejv

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý