zoukankan      html  css  js  c++  java
  • java线程之四 SSL加密传输

    网络传输是存在风险的,因此对服服务端和客户端进行安全校验和传输信息的加密就显得非常的重要。

    上面一句有点拗口,简单解释如下文:

      当客户使用SSL向站点服务器发送请求时,服务器向客户端发送一个证书,客户使用已安装的证书,验证服务器身份,然后检查IP地址(主机名)与客户端连接的主机是否匹配。客户生成可以用来对话的私钥(称为会话密钥),然后用服务者的公钥对它进行加密并将它发送到服务者。服务者用自己的私钥解密,然后用该信息和客户端一样的私有会话密钥。通常在这个阶段使用RSA算法。 
    随后,客户端和服务器端使用私有会话密钥和私钥算法(通常是RC4)进行通信。使用另一个密钥的消息认证码来确保消息的完整性。

    接下来,就一一介绍下如何进行SSL加密的socket通信开发

    一、创建服务端密钥

    命令行执行

    keytool.exe -genkeypair -v -alias sslsocket -keyalg RSA -keystore e:\sslsocket.keystore 

    出现提示输入密码

    输入keystore密码:
            再次输入新密码:
            您的名字与姓氏是什么?
              [Unknown]:  lwx
            您的组织单位名称是什么?
              [Unknown]:  newland
            您的组织名称是什么?
              [Unknown]:  bomc
            您所在的城市或区域名称是什么?
              [Unknown]:  fz
            您所在的州或省份名称是什么?
              [Unknown]:  fj
            该单位的两字母国家代码是什么
              [Unknown]:  zh
            CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh 正确吗?
              [否]:  y

    上述信息只是为了帮助客户端校验服务端证书的信息,测试的时候只需要注意最后提示是否正确的时候 输入y 即可。

    接着出现下面信息

    正在为以下对象生成 1,024 位 RSA 密钥对和自签名证书 (SHA1withRSA)(有效期为 90 天
            ):
                     CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh
            输入<sslsocket>的主密码
                    (如果和 keystore 密码相同,按回车):
            [正在存储 e:\sslsocket.keystore]

    生成密钥sslsocket.keystore后,可以通过下面的命令来查看

    keytool -list  -v -keystore e:\sslsocket.keystore -storepass 123456    

    看到的信息就是之前我们输入的内容了 

    Keystore 类型: JKS
            Keystore 提供者: SUN
            
            您的 keystore 包含 1 输入
            
            别名名称: sslsocket
            创建日期: 2013-5-8
            项类型: PrivateKeyEntry
            认证链长度: 1
            认证 [1]:
            所有者:CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh
            签发人:CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh
            序列号:5189a30d
            有效期: Wed May 08 08:57:49 CST 2013 至Tue Aug 06 08:57:49 CST 2013
            证书指纹:
                     MD5:51:5E:1A:57:1B:B9:18:3A:9B:05:F7:13:E5:06:AB:F0
                     SHA1:11:0E:C8:8B:46:1F:27:FA:12:95:95:4E:1E:29:E7:27:50:2E:E9:48
                     签名算法名称:SHA1withRSA
                     版本: 3
            

    二、生成服务端证书

    keytool.exe -exportcert -v -alias sslsocket -file e:\sslsocket.cer -keystore e:\sslsocket.keystore
    e:\sslsocket.cer 即我们服务端的证书,到这里应该就比较熟悉了
    查看证书信息的命令
    keytool.exe -printcert -v -file e:\sslsocket.cer

    出现的结果如下

        所有者:CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh
            签发人:CN=lwx, OU=newland, O=bomc, L=fz, ST=fj, C=zh
            序列号:5189a30d
            有效期: Wed May 08 08:57:49 CST 2013 至Tue Aug 06 08:57:49 CST 2013
            证书指纹:
                     MD5:51:5E:1A:57:1B:B9:18:3A:9B:05:F7:13:E5:06:AB:F0
                     SHA1:11:0E:C8:8B:46:1F:27:FA:12:95:95:4E:1E:29:E7:27:50:2E:E9:48
                     签名算法名称:SHA1withRSA
                     版本: 3

    三、生成客户端密钥

    有了服务端证书之后,自然就是通过密码来生成客户端的密钥了,命令如下

    keytool.exe -importcert -v -alias sslsocketcer -file e:\sslsocket.cer -keystore e:\sslclient.keystore
    e:\sslclient.keystore 就是客户端的密钥了。

    关于keytool的更多信息可以参考这里:http://blog.chinaunix.net/uid-17102734-id-2830223.html

    四、开发程序

    为了测试 我将服务端和客户端的证书放到工程目录下

    服务端代码

      1 /**
      2  * @author  draem0507@gmail.com
      3  * @TODO    java线程开发之四 SSL加密
      4  * 开发步骤
      5  * 1.生成服务端密钥
      6  * 2.导出服务端证书
      7  * 3.生成客户端密钥
      8  * 4.程序开发测试
      9  * 关于证书的生成请参考readme.txt
     10  * 参考资料:http://chrui.iteye.com/blog/1018778
     11  * @version 1.0
     12  * @date 2013-5-7 23:22:45    
     13  * @update 2013-5-8 10:22:45    
     14  * @blgos http://www.cnblogs.com/draem0507
     15  */
     16 
     17 public class ServerTest {
     18     private ServerSocket serverSocket;
     19     private final static char[] password="123456".toCharArray();
     20     private SSLContext context;
     21     URL url = Thread.currentThread().getContextClassLoader().getResource("sslsocket.keystore");
     22     String path = url.toString();
     23     private InputStream inputStream;
     24     
     25 
     26     public ServerTest() {
     27         inputStream=this.getClass().getResourceAsStream("/sslsocket.keystore");
     28         initContext();
     29         try {
     30             //直接运行会报 javax.net.ssl.SSLException:
     31             //ServerSocketFactory factory=     SSLServerSocketFactory.getDefault();
     32             ServerSocketFactory factory=     context.getServerSocketFactory();
     33 //            serverSocket = new ServerSocket(10000);
     34             serverSocket=factory.createServerSocket(10000);
     35             while (true) {
     36                 Socket socket = serverSocket.accept();
     37                 new ReceiveSocket(socket).start();
     38             }
     39         } catch (IOException e) {
     40             // TODO Auto-generated catch block
     41             e.printStackTrace();
     42         }
     43 
     44     }
     45     
     46     //ssl 上下文对象的初始化
     47     private void initContext() {
     48         try {
     49             KeyStore store=KeyStore.getInstance("JKS");
     50             store.load(inputStream, password);
     51             KeyManagerFactory factory=KeyManagerFactory.getInstance("SunX509");
     52             factory.init(store,password);
     53             KeyManager []keyManagers=factory.getKeyManagers();
     54             context=SSLContext.getInstance("SSL");
     55             context.init(keyManagers, null    , null);
     56         } catch (KeyStoreException e) {
     57             // TODO Auto-generated catch block
     58             e.printStackTrace();
     59         } catch (NoSuchAlgorithmException e) {
     60             // TODO Auto-generated catch block
     61             e.printStackTrace();
     62         } catch (CertificateException e) {
     63             // TODO Auto-generated catch block
     64             e.printStackTrace();
     65         } catch (FileNotFoundException e) {
     66             // TODO Auto-generated catch block
     67             e.printStackTrace();
     68         } catch (IOException e) {
     69             // TODO Auto-generated catch block
     70             e.printStackTrace();
     71         } catch (UnrecoverableKeyException e) {
     72             // TODO Auto-generated catch block
     73             e.printStackTrace();
     74         } catch (KeyManagementException e) {
     75             // TODO Auto-generated catch block
     76             e.printStackTrace();
     77         }
     78         
     79     }
     80 
     81     public static void main(String[] args) {
     82         new ServerTest();
     83 
     84     }
     85 
     86     private class ReceiveSocket extends Thread {
     87         private Socket socket;
     88 
     89         public ReceiveSocket(Socket socket) {
     90             this.socket = socket;
     91         }
     92 
     93         private ObjectInputStream reader;
     94         private ObjectOutputStream writer;
     95 
     96         @Override
     97         public void run() {
     98 
     99             try {
    100                 reader=new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
    101                 //writer=new ObjectOutputStream(socket.getOutputStream());
    102                 // 开启无限循环 监控消息
    103                 
    104                     //java.io.EOFException
    105                 Object obj=    reader.readObject();
    106                     if(obj!=null)
    107                     {
    108                         User user =(User)obj;
    109                         System.out.println("id=="+user.getId()+"\tname=="+user.getName());
    110                     }
    111                 //    while (true) {}
    112 
    113             } catch (IOException e) {
    114                 // TODO Auto-generated catch block
    115                 e.printStackTrace();
    116             } catch (ClassNotFoundException e) {
    117                 // TODO Auto-generated catch block
    118                 e.printStackTrace();
    119             } finally {
    120                 if (null != reader) {
    121                     try {
    122                         reader.close();
    123                     } catch (IOException e) {
    124                         // TODO Auto-generated catch block
    125                         e.printStackTrace();
    126                     }
    127                 }
    128                 if (null != writer) {
    129                     try {
    130                         reader.close();
    131                     } catch (IOException e) {
    132                         // TODO Auto-generated catch block
    133                         e.printStackTrace();
    134                     }
    135                 }
    136                 try {
    137                     socket.close();
    138                 } catch (IOException e) {
    139                     // TODO Auto-generated catch block
    140                     e.printStackTrace();
    141                 }
    142             }
    143 
    144         }
    145 
    146     }
    147 
    148 }

    客户端代码

     1 public class ClientTest {
     2     private final static char[] password="123456".toCharArray();
     3     private static SSLContext context;
     4     static InputStream inputStream=ClientTest.class.getResourceAsStream("/sslclient.keystore");
     5     
     6     public static void main(String[] args) throws Exception {
     7          
     8         KeyStore ts = KeyStore.getInstance("JKS");  
     9         ts.load(inputStream, password);  
    10         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");  
    11         tmf.init(ts);  
    12         TrustManager [] tm = tmf.getTrustManagers();  
    13         context = SSLContext.getInstance("SSL");  
    14         context.init(null, tm, null);  
    15         
    16         //SocketFactory factory=    SSLSocketFactory.getDefault();
    17         //Socket socket =factory.createSocket("localhost", 10000);
    18         SocketFactory factory=    context.getSocketFactory();
    19         SSLSocket socket=(SSLSocket) factory.createSocket("localhost", 10000);
    20         
    21         
    22         //ObjectInputStream in=new ObjectInputStream(socket.getInputStream());
    23         ObjectOutputStream out=new ObjectOutputStream(socket.getOutputStream());
    24         
    25         
    26                 User user =new User();
    27                 user.setId(1);
    28                 user.setName("lwx_"+1);
    29                 out.writeObject(user);
    30                 out.flush();
    31     
    32             
    33         socket.close();
    34         
    35         
    36     }
    37 }

    如果想要源码的话,可以到这里来下载 http://download.csdn.net/detail/draem0507/5343534

  • 相关阅读:
    JS判断年月
    斐波那契数列
    webkit 控件供vb 6 调用,不错~
    webkit com wrapper 推荐!
    firefox usercontrol for donet
    [z] How can we render CSS3 in a WebBrowser Control ?
    A simple way to crack VBA password in Excel file
    putty教程
    Putty建立隧道的方法[z]
    Step By Step Hibernate Tutorial Using eclipse WTP[z]
  • 原文地址:https://www.cnblogs.com/draem0507/p/3067252.html
Copyright © 2011-2022 走看看