SSL协议的优势在于它与应用层协议独立无关,高层的应用层协议如HTTP、SSH,FTP 竺等,能透明的建立于SSL协议之上,在应用层通信之前就已经完成加密算法、通信密钥的协商以及服务端及客户端的认证工作,在此之后所有应用层协议所传输的数据都会被加密,从而保证通信的私密性。
SSL的继任者是TLS协议全称为Transport Layer Security, 即传输层安全协议,是基于SSL协议的通用化协议,同样位于应用层与传输层之间,正逐步接替SSL成为下一代网络安全协议。
SSL/TLS协议均可以分为两层:一层为RecordProtocol, 即记录协议;另一层为Handshake Protocol, 即握手协议。记录协议建立在可靠的传输协议(如TCP)之上,提供数据封装、加密解密、数据压缩、数据校验等基本功能。握手协议建立在记录协议之上,在实际的数据传输开始前,进行加密算法的协商,通信密钥的交换,通信双方身份的认证等工作。
SSL握手协议比较复杂,它大致的工作流程如图:
步骤如下:
1.客户端发送一个客户端的 say hello 信息,消息包含协议的版本信息,sessionid信息,客户端支持的加密算法,压缩算法信息,并且包含客户端产生的随机数。
2.服务端响应server hello信息,消息包含服务端产生的随机数协议版本等等客户端类似的以及服务端数字证书。如果服务端配置的双向认证,这时候服务端还要验证客户端证书。
3.客户端通过证书验证服务端合法性。
4.如果证书验证通过,客户端向服务端发送经过服务端加密的预主密钥(PreMaster Secret)PMS.假如服务端在上一个步骤请求了客户端证书,客户端会将客户端证书发送给服务端校验。
5.服务端验证证书有效,并通过自己私钥对PMS进行解密,使用客户端发送的随机数和服务端发送的随机数,加上解密的PMS来生成主密钥(MS),然后通过主密钥来生成加密密钥。
6.客户端也将使用两个随机数加上PMS生成MS,然后通过MS生成加密密钥。
客户端:
7.通知服务端未来信息使用加密密钥加密。
8.给服务端发送加密密钥来加密信息,终止握手。
服务端
9.通知客户端使用加密密钥加密。
10.给客户端发送加密密钥,终止握手。
在服务端与客户端真正的数据交换阶段,实际上数据是通过对称加密算法来实现加密的,密钥为双方约定好的加密密钥。客户端首先使用加密密钥来加密请求内容,发送给服务端,服务端使用加密密钥对请求进行解密并处理相应的汕求,然后生成响应内容。响应经过加密密钥。加密后,发送给客户端,客户端通过加密密钥对响应内容进行解密,以获得响应内容。
SSL握手协议十分复杂,对于并非密码学专家的普通开发人员来说,理解上述交互过程确实不那么容易,更别说对SSL/TLS协议进行实现。对于普通开发人员来说,他们关心的并不是如何实现SSL/TLS协议,而是如何才能让他们的程序以最简洁的方式接入SSL/TLS强大的安全保护功能,JSSE正是这样的一个工具。
JSSE (Java Security Socket Extension)是Sun公司为了解决互联网信息安全传输提出的一个解决方案,它实现了SSL和TSL协议,包含了数据加密、服务器验证、消息完整性和客户端验证等技术。通过使用JSSE简洁的APL可以在客户端和服务端之间通过SSL/TSL协议安全地传输数据。
首先,需要将前面3.2.5节所生成的客户端及服务端私钥和数字证书进行导出,生成Java环境可用的keystore文件。
客户端私钥与证书的导出:
openssl pkcs12 -export -clcerts -name 客户端姓名(例如: zengxinyao) -inkey private/client-key.pem -in certs/client.cer -out /home/longlong/temp/testssl/client.keystore
服务端证书的导出:
openssl pkcsl2 -export -cl certs -name www. codeaholic. net -in key private/ server-key.pern -in certs/server.cer -out /horne/longlong/ternp/testssl/server.keystore
信任证书的导出:
由于客户端与服务端证书都是由下面的CA所颁发认证的,因此只需要将下面CA的根证书作为信任库,就可以对以上的客户端与服务端证书进行识别。
keytool -importcert -trustcacerts -alias *.codeaholic.net -file /home/longlong/ ca_dir/certs/ca.cer -keystore/home/longlong/temp/testssl/ca-trust.keystore
使用 J S S E 进行 S S L /T S L 协议数据传输。
Java 实现的通信客户端。
SSLSocket 初始化:
初始化时首先取得 SSLContext、KeyManagerF actory 、TrustManagerFactory 的实例,然后加载客户端的密钥库和信任库到相应的 K eyStore, 对KeyManagerFactory 和 TrustM anagerFactory 进行初始化,最后用 K eyManager Factory 和 TrustM anagerFactory 对 SSLC ontext进行初始化,并创建 SSLSocket。
进行 SSL 通信:
使用 SSLSocket 与使用 Socket 其实区别不大,process 方法将给服务端发送 "hello chenkangxian ! "这个字符串,并解析服务端的返回,然后进行输出。
Java实现的通信服务端。
与客户端的初始化类似,服务端初始化时也是先取得 SSLContext、K eyM anagerFactory、 TrustManagerFactory 的实例,然后加载服务端的密钥库和信任库到相应的 K eyStore, 对Key Manager Factory 和 TrustM anagerFactory 进行初始化 ,最后用 K eyManagerF actory 和TrustManagerF actory 对 SSLContext进行初始化,并创建 SSLServerSocket。
服务端的 SSLServerSocket将在循环中不断地接收客户端的请求,将客户端传过来的字符串打印,并返回给客户端 "bye bye!"。
摘自:
《大型分布式网站架构设计与实践》 阅读笔记