客户端和服务器端证书的生成,请看:
http://my.oschina.net/xinxingegeya/blog/266826
http://www.ibm.com/developerworks/cn/java/j-lo-socketkeytool/
参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-socketkeytool/
参考文章:http://willtea.iteye.com/blog/1841281
本篇主要关于SSLContext,及其设置证书库和信任库
// 相关的 jks 文件及其密码定义 private final static String CERT_STORE="D:/test_server_cert.jks"; private final static String CERT_STORE_PASSWORD="Testpassw0rd"; // 载入 jks 文件 FileInputStream f_certStore=new FileInputStream(CERT_STORE); KeyStore ks=KeyStore.getInstance("jks"); ks.load(f_certStore, CERT_STORE_PASSWORD.toCharArray()); f_certStore.close(); // 创建并初始化证书库工厂 String alg=KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg); kmFact.init(ks, CERT_STORE_PASSWORD.toCharArray()); KeyManager[] kms=kmFact.getKeyManagers(); // 创建并初始化 SSLContext 实例 SSLContext context=SSLContext.getInstance("SSL"); context.init(kms, null, null); SSLServerSocketFactory ssf=(SSLServerSocketFactory)context.getServerSocketFactory();
// 相关的 jks 文件及其密码定义 private final static String TRUST_STORE="D:/test_client_trust.jks"; private final static String TRUST_STORE_PASSWORD="Testpassw0rd"; // 载入 jks 文件 FileInputStream f_trustStore=new FileInputStream(TRUST_STORE); KeyStore ks=KeyStore.getInstance("jks"); ks.load(f_trustStore, TRUST_STORE_PASSWORD.toCharArray()); f_trustStore.close(); // 创建并初始化信任库工厂 String alg=TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmFact=TrustManagerFactory.getInstance(alg); tmFact.init(ks); TrustManager[] tms=tmFact.getTrustManagers(); // 创建并初始化 SSLContext 实例 SSLContext context=SSLContext.getInstance("SSL"); context.init(null, tms, null); SSLSocketFactory sf=context.getSocketFactory();
当然,如果要在服务端或者客户端同时使用证书库和信任库,可将清单 3 和清单 4 的代码用在同一处 context.init() 的地方。
这里需要说明的是,如果 context.init() 的第一个 KeyManager[] 参数为 null,则表示不提供证书;如果第二个 TrustManager[] 参数为 null,则会寻找系统默认提供的信任库 ( 例如:JRE 安装目录下的 lib/security/cacerts)。
package ssl4; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.security.KeyStore; import javax.net.ServerSocketFactory; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.TrustManagerFactory; public class SSLServer extends Thread { private Socket socket; public SSLServer(Socket socket) { this.socket = socket; } public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter writer = new PrintWriter(socket.getOutputStream()); String data = reader.readLine(); writer.println(data); writer.close(); socket.close(); } catch (IOException e) { } } private static String SERVER_KEY_STORE = "E:\\javassl2\\sslserverkeys"; private static String SERVER_TRUST_KEY_STORE = "E:\\javassl2\\sslservertrust"; private static String SERVER_KEY_STORE_PASSWORD = "123456"; private static String SERVER_TRUST_KEY_STORE_PASSWORD = "123456"; public static void main(String[] args) throws Exception { //加载证书库 KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(SERVER_KEY_STORE), SERVER_KEY_STORE_PASSWORD.toCharArray()); //加载信任库 KeyStore trustKs = KeyStore.getInstance("JKS"); trustKs.load(new FileInputStream(SERVER_TRUST_KEY_STORE), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray()); //创建并初始化证书库工厂 String alg = KeyManagerFactory.getDefaultAlgorithm(); // KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509"); KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg); kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray()); // 创建并初始化信任库工厂 String alg_trust = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg_trust); tmf.init(trustKs); SSLContext context = SSLContext.getInstance("TLS"); context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); /** * 通过SSLContext得到serverSocketFactory */ ServerSocketFactory factory = context.getServerSocketFactory(); ServerSocket _socket = factory.createServerSocket(8443); ((SSLServerSocket) _socket).setNeedClientAuth(true); while (true) { new SSLServer(_socket.accept()).start(); } } }
package ssl4; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.security.KeyStore; import javax.net.SocketFactory; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class SSLClient { private static String CLIENT_KEY_STORE = "E:\\javassl2\\sslclientkeys"; private static String CLIENT_TRUST_KEY_STORE = "E:\\javassl2\\sslclienttrust"; private static String CLIENT_KEY_STORE_PASSWORD = "123456"; private static String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456"; public static void main(String[] args) throws Exception { SSLClient client = new SSLClient(); Socket s = client.clientWithCert(); PrintWriter writer = new PrintWriter(s.getOutputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream())); writer.println("hello"); writer.flush(); System.out.println(reader.readLine()); s.close(); } private Socket clientWithoutCert() throws Exception { SocketFactory sf = SSLSocketFactory.getDefault(); Socket s = sf.createSocket("localhost", 8443); return s; } private Socket clientWithCert() throws Exception { //加载证书库 KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(CLIENT_KEY_STORE), CLIENT_KEY_STORE_PASSWORD.toCharArray()); //加载信任库 KeyStore trustKs = KeyStore.getInstance("JKS"); trustKs.load(new FileInputStream(CLIENT_TRUST_KEY_STORE), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray()); //创建并初始化证书库工厂 String alg = KeyManagerFactory.getDefaultAlgorithm(); // KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509"); KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg); kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray()); // 创建并初始化信任库工厂 String alg_trust = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg_trust); tmf.init(trustKs); /** * TLS安全套接字 * Returns a SSLContext object that implements the specified secure socket protocol. */ SSLContext context = SSLContext.getInstance("TLS"); context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SocketFactory factory = context.getSocketFactory(); Socket s = factory.createSocket("localhost", 8443); return s; } }