ssl加密 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

输入的主密码

(如果和 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 *@authordraem0507@gmail.com3 * @TODO java线程开发之四 SSL加密4 * 开发步骤5 * 1.生成服务端密钥6 * 2.导出服务端证书7 * 3.生成客户端密钥8 * 4.程序开发测试9 * 关于证书的生成请参考readme.txt10 * 参考资料:http://chrui.iteye.com/blog/1018778

11 *@version1.012 * @date 2013-5-7 23:22:4513 * @update 2013-5-8 10:22:4514 * @blgoshttp://www.cnblogs.com/draem0507

15 */

16

17 public classServerTest {18 privateServerSocket serverSocket;19 private final static char[] password="123456".toCharArray();20 privateSSLContext context;21 URL url = Thread.currentThread().getContextClassLoader().getResource("sslsocket.keystore");22 String path =url.toString();23 privateInputStream inputStream;24

25

26 publicServerTest() {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 newReceiveSocket(socket).start();38 }39 } catch(IOException e) {40 //TODO Auto-generated catch block

41 e.printStackTrace();42 }43

44 }45

46 //ssl 上下文对象的初始化

47 private voidinitContext() {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 voidmain(String[] args) {82 newServerTest();83

84 }85

86 private class ReceiveSocket extendsThread {87 privateSocket socket;88

89 publicReceiveSocket(Socket socket) {90 this.socket =socket;91 }92

93 privateObjectInputStream reader;94 privateObjectOutputStream writer;95

96 @Override97 public voidrun() {98

99 try{100 reader=new ObjectInputStream(newBufferedInputStream(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 classClientTest {2 private final static char[] password="123456".toCharArray();3 private staticSSLContext context;4 static InputStream inputStream=ClientTest.class.getResourceAsStream("/sslclient.keystore");5

6 public static void main(String[] args) throwsException {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=newObjectOutputStream(socket.getOutputStream());24

25

26 User user =newUser();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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值