Java内置了对HTTPS和SSL的支持,但是我在写客户端时遇到了一些问题,比如最大的问题就是在连接的服务器没有一个有效的(也就是经过根CA认证的)SSL证书时会报错。Google了一下,说有两种方式:一种是事先把目标证书导入Java的证书管理器里,另一种是强制忽略证书合法性检查。第一种方法不用对代码进行什么更改,只要运行一个命令就行了,但是缺点是每次服务器更换证书都要进行一次导入。
第二种方法需要更改一下代码,优点是可以应用于任何SSL证书,而且不用重复导入,缺点也很明显,降低了系统的安全性。
下面是第二钟方法的实例代码
try { final SSLContext sslContext = SSLContext.getInstance("TLSv1"); sslContext.init(null, new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { //这里进行有效性检查,不抛出异常就算检查成功 } public X509Certificate[] getAcceptedIssuers() { return null; } } }, null); sleep(100); SSLSocketFactory factory = sslContext.getSocketFactory(); final SSLSocket socket = (SSLSocket) factory.createSocket("127.0.0.1", 4433); SSLSession session = socket.getSession(); X509Certificate cert = null; try { cert = (X509Certificate) session.getPeerCertificates()[0]; } catch (SSLPeerUnverifiedException e) { e.printStackTrace(); System.err.println(session.getPeerHost() + " did not present a valid certificate"); return; } System.out.println(session.getPeerHost() + " has presented a certificate belonging to" + "[" + cert.getSubjectDN() + "]\n" + "The certificate was issued by: \t" + "[" + cert.getIssuerDN() + "]"); PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.println("GET /index.html HTTP/1.0"); pw.println("Server: mail.google.com"); pw.println("Connection: close"); pw.println(); pw.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String ln; while ((ln = in.readLine()) != null) { System.err.println(ln); } } catch (Exception ex) { Logger.getLogger(ServerLauncher.class.getName()).log(Level.SEVERE, null, ex); }