Java – javax. net. ssl. Sslpeerunverifiedexception: peer is not authenticated
I am trying to connect to my own SSL server using my own SSL client, but I received the following error:
javax. net. ssl. Sslpeerunverifiedexception: peer is not authenticated at sun security. ssl. SSLSessionImpl. Getpeercertificatechain (sslsessionimpl. Java: 420) is in server Run (server. Java: 70) in server main(Server.java:22)
I searched stack overflow for the same problem, but I can only find people who use it in Apache or other HTTPS "systems"
This is my server code:
/* Server SSL */ import javax.net.ssl.*; import java.io.*; import java.net.InetAddress; import java.security.KeyStore; //import java.security.cert.X509Certificate; import java.util.Date; import javax.security.cert.X509Certificate; class server { ObjectOutputStream out; ObjectInputStream in; public static void main(String[] args) { new server().run(); } void run() { Date date = new Date(); try { // Security test (to avoid starting from the command line)c char[] passphrase = "password".tocharArray(); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream("/home/ME/CERT/keystore"),passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keystore,passphrase); SSLContext context = SSLContext.getInstance("TLS"); KeyManager[] keyManagers = kmf.getKeyManagers(); context.init(keyManagers,null,null); // -- End of security test // 1. Create a server Socket SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999); // TBH im not sure what the following code does,but I need it? String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" }; sslserversocket.setEnabledCipherSuites(enabledCipherSuites); // 2. Wait for connection. System.out.println("Waiting for connection. "); SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); SSLSession session = sslsocket.getSession(); X509Certificate cert = (X509Certificate)session.getPeerCertificateChain()[0]; String subject = cert.getSubjectDN().getName(); System.out.println(subject); // 2.1 Prints information about client,this Could be (very) valuable to save in a file. System.out.println("Connection received: "); System.out.println(" Hostname: " + sslsocket.getInetAddress().getHostName()); sslsocket.getInetAddress(); System.out.println(" IP: " + InetAddress.getLocalHost().getHostAddress()); System.out.println(" @ " + date.toString()); System.out.println(); // 3. Create input and output streams. // for some reason i cant make the out/in-variable without using it as global? out = new ObjectOutputStream(sslsocket.getOutputStream()); out.flush(); in = new ObjectInputStream(sslsocket.getInputStream()); sendMessage("Connection successful"); // 4. Client and server talks via the input and output streams String message; do { message = (String)in.readObject(); System.out.println(" Client says: " + message); if (message.equals("bye")) { sendMessage("bye"); } }while(!message.equals("bye")); // 5. Closing connection in.close(); out.close(); sslsocket.close(); System.out.println("Server terminated. "); } catch (Exception exception) { exception.printStackTrace(); } } void sendMessage(String msg) throws Exception { out.writeObject(msg); out.flush(); System.out.println(" You(server) says: " + msg); } }
This is my customer code:
/* Java SSL Client */ import javax.net.ssl.*; import java.io.*; import java.security.KeyStore; import java.util.*; class client { String message; ObjectOutputStream out; ObjectInputStream in; public static void main(String[] args) { new client().run(); } void run() { System.out.println(); int port = 9999; String host = "127.0.0.1"; try { // Security test (to avoid starting with the command line) char[] passphrase = "trustword".tocharArray(); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream("/home/ME/CERT/truststore"),passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(keystore); SSLContext context = SSLContext.getInstance("TLS"); TrustManager[] trustManagers = tmf.getTrustManagers(); context.init(null,trustManagers,null); // --- End of security test System.out.println("Connecting to " + host + " on port " + port); // 1. Create a client socket. SSLSocketFactory sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket sslSocket = (SSLSocket)sslFactory.createSocket(host,port); // TBH im not sure what the following code does,but I need it? String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" }; sslSocket.setEnabledCipherSuites(enabledCipherSuites); System.out.println("Connected."); // 2. Create input and output streams out = new ObjectOutputStream(sslSocket.getOutputStream()); out.flush(); in = new ObjectInputStream(sslSocket.getInputStream()); // 3. Client and server talks via the input and output streams Scanner input = new Scanner(system.in); message = (String)in.readObject(); System.out.println(" Server says: " + message); sendMessage("Hello Server! "); do { // Sends input text System.out.print("Enter text to send: "); message = input.nextLine(); sendMessage(message); if (message.equals("bye")) { message = (String)in.readObject(); System.out.println(" Server says: " + message); } } while(!message.equals("bye")); // 4. Closing connection in.close(); out.close(); sslSocket.close(); System.out.println("Client terminated. "); } catch (Exception exception) { exception.printStackTrace(); } } void sendMessage(String msg) throws Exception { out.writeObject(msg); out.flush(); System.out.println(" You(client) says: " + msg); }
}
I am very grateful for the answer, or work in the right direction!
Solution
Here are two questions
>You are limiting the cipher suite to SSL_ DH_ anon_ WITH_ RC4_ 128_ MD5, which is an anonymous Password Suite, so there is no authentication Just delete it, you don't need it. > You did not call setwantclientauth (true) or setneedclientauth (true) on the server, so the client will never be asked to send its certificate, so it will not send the certificate Therefore, it makes no sense for the server to request a peer certificate Let the customer ask for it
At this point, you need to determine whether client authentication is really required If you do so, you must call one of the above methods, and you also need to provide the private key and signing certificate for the client in the keystore, and trust the keystore through exporting / importing or arranging the truststore of the server Sign client certificate through ca It's not clear whether you need these