2008年7月3日星期四

Java在处理SSL时证书无效的问题,以及解决方法

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);
}

0 人次吐槽:

发表评论