Java – javax.net.ssl.SSLPeerUnverifiedException:peer未经过
我正在尝试使用自己的SSL客户端连接到我自己的SSL服务器,但是我收到以下错误:
javax.net.ssl.SSLPeerUnverifiedException:peer未经过身份验证 我在stackoverflow上搜索了同样的问题,但我只能找到在Apache或其他HTTPS“系统”中使用它的人. 这是我的服务器代码: /* 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); } } 这是我的客户代码: /* 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); } } 我非常感谢答案,或者朝着正确的方向努力! 解决方法
这里有两个问题.
>您正在将密码套件限制为SSL_DH_anon_WITH_RC4_128_MD5,这是一个匿名密码套件,因此没有身份验证.只需删除它,你不需要它. 此时,您需要确定是否确实需要客户端身份验证.如果这样做,则必须调用上述方法之一,并且还需要在密钥库中为客户端提供私钥和签名证书,并通过导出/导入或安排服务器的信任库信任此密钥库.通过CA签署客户端证书.目前还不清楚你是否需要这些. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |