我们常见的SSL验证较多的只是验证我们的服务器是否是真实正确的,当然如果你访问的URL压根就错了,那谁也没有办法。这个就是所谓的SSL单向认证。
但是实际中,我们有可能还会验证客户端是否符合要求,也就是给我们每个用户颁发一个证书,比且每个数字证书都是唯一的,不公开的。这样就能通过这个数字证书保证当前访问我服务器的这个用户是经过服务器认可的,其他人不可访问。
双向认证 从第一个层面上 确保了服务器 与客户端 都是互相认可的。那么他们之间要进行通信,就会在通信协议上附加SSL协议,确保通信的内容是加密的,即使是sniffer这样的网络嗅探工具看到的都是 乱码。以后给大家演示下不加密的情况下,用sniffer看到的是什么。恐怕这样你就能提高警惕了。
以下内容从网络上摘抄 加以实际验证后修改的。
在这里我还是推荐使用Java自带的keytool命令,去生成这样信息文件。当然目前非常流行的开源的生成SSL证书的还有OpenSSL。 OpenSSL用C语言编写,跨系统。但是我们可能在以后的过程中用java程序生成证书的方便性考虑,还是用JDK自带的keytool。

以下是通过Java Socket通信程序来验证我们生成的证书是否可用。
客户端:
- package examples.ssl;
-
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.security.KeyStore;
-
- import javax.net.ssl.KeyManagerFactory;
- import javax.net.ssl.SSLContext;
- import javax.net.ssl.SSLSocket;
- import javax.net.ssl.TrustManagerFactory;
-
- /
- SSL Client
-
- */
- public class SSLClient {
-
- private static final String DEFAULT_HOST = “127.0.0.1”;
- private static final int DEFAULT_PORT = 7777;
-
- private static final String CLIENT_KEY_STORE_PASSWORD = “”;
- private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = “”;
-
- private SSLSocket sslSocket;
-
- /
- 启动客户端程序
-
- @param args
- /
- public static void main(String[] args) {
- SSLClient client = new SSLClient();
- client.init();
- client.process();
- }
-
- /
- 通过ssl socket与服务端进行连接,并且发送一个消息
- /
- public void process() {
- if (sslSocket == null) {
- System.out.println(“ERROR”);
- return;
- }
- try {
- InputStream input = sslSocket.getInputStream();
- OutputStream output = sslSocket.getOutputStream();
-
- BufferedInputStream bis = new BufferedInputStream(input);
- BufferedOutputStream bos = new BufferedOutputStream(output);
-
- bos.write(“Client Message”.getBytes());
- bos.flush();
-
- byte[] buffer = new byte[20];
- bis.read(buffer);
- System.out.println(new String(buffer));
-
- sslSocket.close();
- } catch (IOException e) {
- System.out.println(e);
- }
- }
-
- /
- <ul>
- <li>ssl连接的重点:</li>
- <li>初始化SSLSocket</li>
- <li>导入客户端私钥KeyStore,导入客户端受信任的KeyStore(服务端的证书)</li>
- </ul>
- /
- public void init() {
- try {
- SSLContext ctx = SSLContext.getInstance(“SSL”);
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(“SunX509”);
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(“SunX509”);
-
- KeyStore ks = KeyStore.getInstance(“JKS”);
- KeyStore tks = KeyStore.getInstance(“JKS”);
-
- ks.load(new FileInputStream(“E://kclient.keystore”), CLIENT_KEY_STORE_PASSWORD.toCharArray());
- tks.load(new FileInputStream(“E://tclient.keystore”), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
-
- kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
- tmf.init(tks);
-
- ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-
- sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);
- } catch (Exception e) {
- System.out.println(e);
- }
- }
-
- }
服务器端:
- package examples.ssl;
-
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.security.KeyStore;
-
- import javax.net.ssl.KeyManagerFactory;
- import javax.net.ssl.SSLContext;
- import javax.net.ssl.SSLServerSocket;
- import javax.net.ssl.TrustManagerFactory;
-
- /*
- <ul>
- <li>1)生成服务端私钥</li>
- <li>keytool -genkey -alias serverkey -keystore kserver.keystore</li>
- <li>2)根据私钥,到处服务端证书</li>
- <li>keytool -exoport -alias serverkey -keystore kserver.keystore -file server.crt</li>
- <li>3)把证书加入到客户端受信任的keystore中</li>
- <li>keytool -import -alias serverkey -file server.crt -keystore tclient.keystore</li>
- </ul>
- /
-
- /
- SSL Server
-
- */
- public class SSLServer {
-
- private static final int DEFAULT_PORT = 7777;
-
- private static final String SERVER_KEY_STORE_PASSWORD = “”;
- private static final String SERVER_TRUST_KEY_STORE_PASSWORD = “”;
-
- private SSLServerSocket serverSocket;
-
- /
- 启动程序
-
- @param args
- /
- public static void main(String[] args) {
- SSLServer server = new SSLServer();
- server.init();
- server.start();
- }
-
- /
- <ul>
- <li>听SSL Server Socket</li>
- <li> 由于该程序不是演示Socket监听,所以简单采用单线程形式,并且仅仅接受客户端的消息,并且返回客户端指定消息</li>
- </ul>
- */
- public void start() {
- if (serverSocket == null) {
- System.out.println(“ERROR”);
- return;
- }
- while (true) {
- try {
- Socket s = serverSocket.accept();
- InputStream input = s.getInputStream();
- OutputStream output = s.getOutputStream();
-
- BufferedInputStream bis = new BufferedInputStream(input);
- BufferedOutputStream bos = new BufferedOutputStream(output);
-
- byte[] buffer = new byte[20];
- bis.read(buffer);
- System.out.println(new String(buffer));
-
- bos.write(“Server Echo”.getBytes());
- bos.flush();
-
- s.close();
- } catch (Exception e) {
- System.out.println(e);
- }
- }
- }
-
- /*
- <ul>
- <li>ssl连接的重点:</li>
- <li>初始化SSLServerSocket</li>
- <li>导入服务端私钥KeyStore,导入服务端受信任的KeyStore(客户端的证书)</li>
- </ul>
- */
- public void init() {
- try {
- SSLContext ctx = SSLContext.getInstance(“SSL”);
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(“SunX509”);
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(“SunX509”);
-
- KeyStore ks = KeyStore.getInstance(“JKS”);
- KeyStore tks = KeyStore.getInstance(“JKS”);
-
- ks.load(new FileInputStream(“E://kserver.keystore”), SERVER_KEY_STORE_PASSWORD.toCharArray());
- tks.load(new FileInputStream(“E://tserver.keystore”), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
-
- kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
- tmf.init(tks);
-
- ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-
- serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
- serverSocket.setNeedClientAuth(true);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
http://blog.csdn.net/binyao0/article/details/
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/14487.html