SSL/TLS的工作原理
l 基本概念
ü SSL(Secure Socket Layer)是netscape公司设计的主要用于web的安全传输协议。这种协议在WEB上获得了广泛的应用。
ü IETF(www.ietf.org)将SSL作了标准化,即RFC2246,并将其称为TLS(Transport Layer Security),从技术上讲,TLS 1.0与SSL 3.0的差别非常微小。
ü 基本原理:先非对称加密传递对称加密所要用的钥匙,然后双方用该钥匙对称加密和解米往来的数据。
l 工作过程
ü 浏览器向服务器发出请求,询问对方支持的对称加密算法和非对称加密算法;服务器回应自己支持的算法。
ü 浏览器选择双方都支持的加密算法,并请求服务器出示自己的证书;服务器回应自己的证书。
ü 浏览器随机产生一个用于本次会话的对称加密的钥匙,并使用服务器证书中附带的公钥对该钥匙进行加密后传递给服务器;服务器为本次会话保持该对称加密的钥匙。第三方不知道服务器的私钥,即使截获了数据也无法解密。非对称加密让任何浏览器都可以与服务器进行加密会话。
ü 浏览器使用对称加密的钥匙对请求消息加密后传送给服务器,服务器使用该对称加密的钥匙进行解密;服务器使用对称加密的钥匙对响应消息加密后传送给浏览器,浏览器使用该对称加密的钥匙进行解密。第三方不知道对称加密的钥匙,即使截获了数据也无法解密。对称加密提高了加密速度。
l 要求
ü 服务器端需安装数字证书,用户可能需要确认证书。
ü 会话过程中的加密与解密过程由浏览器与服务器自动完成,对用户完全透明。
SSL 和 HTTPS 不仅可以加密通信,而且可以用于服务器和客户身份的验证。
在jdk帮助文档的jsse部分,可以看到SSL工作原理介绍的内容。
使用keytool创建证书时,刚开始设置的用户名一定要是服务器的域名,否则,浏览器进行访问时也将提示证书有问题:
1.一种情况是发证机关是否值得信赖的,好比你拿出来的驾照是不是交管局这样的国家法定机构颁发的,还是你们村的村支书自己盖的章。
2.还有一种就是证书机构确实是交管局颁发的,但并不是发给你的,而是发给你老婆的,你出示你老婆的驾照时,人家交警会问,这是我们发的证,但是是发给你的吗?
讲课时,刚开始创建的证书的用户故意不给localhost,实验失败后,再将老的证书的名称修改为其他名称,接着再创建一个给localhost的新证书,并且证书别名用老证书的名称,这样,就不用修改服务器端的配置,但要重新启动服务器才能生效。
SSL编程——默认参数方式
l 服务器端程序
• 调用getDefault()静态方法得到SSLServerSocketFactory实例对象
• 需要通过javax.net.ssl.keyStore和javax.net.ssl.keyStorePassword系统属性指定keystore的位置与密码,否则,KeyManager管理一个空的keystore,这可以通过在jsse文档中搜索getDefault关键字获知。
• 调用SSLServerSocketFactory对象的createServerSocket()方法得到ServerSocket。
• 循环调用ServerSocket.accept()等待外部连接,并启动新线程与每个连接的客户端进行对话。
• 打开浏览器进行访问测试,必须在keystore中存入与主机名相一致的keyEntry,且将该keyEntry的证书安装到浏览器中。
l 客户端编程:
• 调用getDefault()静态方法得到SSLSocketFactory实例对象
• 需要通过javax.net.ssl.trustStore系统属性指定truststore的位置,由于不需要读取私钥信息,所以不用设置keystore的密码。
• 如果没有设置javax.net.ssl.trustStore系统属性,则查找<java-home>/lib/security/jssecacerts,没找到则接着查找<java-home>/lib/security/cacerts。
• 如果上面的默认的truststore没有找到,则TrustManager管理一个空的trueststore,这可以通过在jsse文档中搜索getDefault关键字获知。
• 调用SSLSocketFactory对象的createSocket()方法连接服务器,连接成功后与服务器进行对话。
• 运行客户端程序进行测试访问,如果服务器出示的证书不是由客户端已经信任的CA签名的,则必须在truststore中导入服务器端的证书。
在这种采用默认参数的方式下,服务器端的keystore中只能存储一个keyEntry,否则,服务器程序就面临不知道选用哪个keyEntry的问题了。
客户端导入证书时执行的命令为:C:\Java\jdk1.6.0_21\bin>keytool -importcert -keystoreC:\Java\jdk1.6.0_21\jre\lib\security\cacerts -file zxx1.cer
baidu搜索SSLServerSocket,即有了参考代码。
服务器端代码:
publicvoid init1()throws Exception{
Stringuser_home = System.getProperty("user.home");
System.out.println(user_home);
System.setProperty("javax.net.ssl.keyStore",user_home+ "/.keystore");
System.setProperty("javax.net.ssl.keyStorePassword","123456");
ServerSocketFactoryfactory = SSLServerSocketFactory.getDefault();
ServerSocketss = factory.createServerSocket(443);
while(true){
Sockets = ss.accept();
newThread(new Worker(s)).start();
}
}
privateclass Worker implements Runnable{
Sockets = null;
publicWorker(Socket s){
this.s= s;
}
publicvoid run() {
try {
bytebuf[] = new byte[10240];
intlen = s.getInputStream().read(buf);