理解一个设计思想,结合代码是最好的途径。安全套接字服务端的实现代码如下:
X509TrustManager MyX509TrustManager = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { System.out.println("getAcceptedIssuers"); return null; } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { System.out.println("checkServerTrusted:"+authType+"////"+chain.length); } public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException { System.out.println("checkClientTrusted"); } }; try { //此文件是Keytool工具生成的证书(生成的路径在cmd目录下) String keyName = "C:/cnkey"; //String keyName = "cnkey"; char[] keyPwd = "123456".toCharArray(); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); //可以直接在src路径下加载文件名为keyName的文件,返回输入流 // Test2.class.getClassLoader().getResourceAsStream(keyName) // 装载当前目录下的key store. 可用jdk中的keytool工具生成keystore InputStream in = new FileInputStream(keyName); keyStore.load(in, keyPwd); in.close(); // 初始化key manager factory KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory .getDefaultAlgorithm()); kmf.init(keyStore, keyPwd); // 初始化ssl context SSLContext context = SSLContext.getInstance("SSL"); context.init(kmf.getKeyManagers(), new TrustManager[] { MyX509TrustManager }, new SecureRandom()); // 监听和接收客户端连接 SSLServerSocketFactory factory = context.getServerSocketFactory(); SSLServerSocket server = (SSLServerSocket) factory .createServerSocket(10002); System.out.println("ok"); Socket client = server.accept(); System.out.println(client.getRemoteSocketAddress()); // 向客户端发送接收到的字节序列 OutputStream output = client.getOutputStream(); // 当一个普通 socket 连接上来, 这里会抛出异常 // Exception in thread "main" javax.net.ssl.SSLException: Unrecognized // SSL message, plaintext connection? InputStream input = client.getInputStream(); byte[] buf = new byte[1024]; int len = 0; while ((len = input.read(buf))!=-1) { String sf = new String(buf, 0, len); System.out.print(sf); if(sf.contains(" ")){ break; } } String html = "<html><head><title>wv</title></head><body><h2>as</h2></body><html>"; String s = "HTTP/1.1 200 OK" + " " + "Date: Sat, 31 Dec 2005 23:59:59 GMT" + " " + "Content-Type: text/html;charset=ISO-8859-1" + " " + "Content-Length: " + html.length() + " " + " " + html; output.write(s.getBytes()); output.flush(); output.close(); input.close(); // 关闭socket连接 client.close(); server.close(); } catch (Exception e) { e.printStackTrace(); }
客户端的代码实现如下:
X509TrustManager MyX509TrustManager = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { System.out.println("getAcceptedIssuers"); return null; } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { System.out.println("checkServerTrusted:"+authType+"////"+chain.length); } public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException { System.out.println("checkClientTrusted"); } }; try { SSLContext context = SSLContext.getInstance("SSL"); // 初始化 context.init(null,new TrustManager[] { MyX509TrustManager },new SecureRandom()); SSLSocketFactory factory = context.getSocketFactory(); SSLSocket s = (SSLSocket) factory.createSocket("localhost", 10002); System.out.println("ok"); OutputStream output = s.getOutputStream(); InputStream input = s.getInputStream(); output.write("alert ".getBytes()); System.out.println("sent: alert"); output.flush(); byte[] buf = new byte[1024]; int len = 0; while ((len = input.read(buf))!=-1) { System.out.println("received:" + new String(buf, 0, len)); } } catch (Exception e) { e.printStackTrace(); }