java的ssl的一点问题,没搞定

服务端是一个基于mina开发的socket server, 连接采用ssl加密。 在服务端即配置了mina的SSLFilter.

客户端的c程序访问的时候,是一切正常的。 而使用java作为客户端,不论是用mina还是直接自己写SSlContext获得socketFactory,结果都一样,有2个怪异的现象。
1. tcp的3次握手完成之后,应该开始进行ssl握手,但是客户端发出的clientHello包却经过了明显的延迟(170ms左右)才发出来。
2. 最后的结束,不是正确的tcp 4次挥手 fin/ack/fin/ack。 而是最后以rst结束。 (猜测是ssl的 close_notify包处理的不正确?)
尽管有这2个现象的存在,但数据的交互却完全是正常的。 如果不是用tcpdump去抓包的话,甚至不会知道底下出现了这样怪异的现象。google也找不到有用的信息。

tcpdump抓包结果如下:

20:12:31.895990 IP 10.18.65.39.47552 > 10.108.90.237.8080: S 1674804305:1674804305(0) win 29200 <mss 1460,sackOK,timestamp 7589134 0,nop,wscale 7>
20:12:31.896079 IP 10.108.90.237.8080 > 10.18.65.39.47552: S 1592612872:1592612872(0) ack 1674804306 win 14480 <mss 1460,sackOK,timestamp 1355739116 7589134,nop,wscale 7>
20:12:31.896521 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1 win 229 <nop,nop,timestamp 7589134 1355739116>
20:12:32.066097 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 1:155(154) ack 1 win 229 <nop,nop,timestamp 7589177 1355739116>
20:12:32.066192 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 155 win 122 <nop,nop,timestamp 1355739287 7589177>
20:12:32.095820 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1:1192(1191) ack 155 win 122 <nop,nop,timestamp 1355739316 7589177>
20:12:32.096437 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1192 win 251 <nop,nop,timestamp 7589184 1355739316>
20:12:32.114039 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 155:230(75) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114100 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 230:236(6) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114124 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 236:289(53) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114572 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 289 win 122 <nop,nop,timestamp 1355739335 7589189>
20:12:32.124198 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1192:1198(6) ack 289 win 122 <nop,nop,timestamp 1355739345 7589189>
20:12:32.161404 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1198 win 251 <nop,nop,timestamp 7589201 1355739345>
20:12:32.161459 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1198:1251(53) ack 289 win 122 <nop,nop,timestamp 1355739382 7589201>
20:12:32.161926 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1251 win 251 <nop,nop,timestamp 7589201 1355739382>
20:12:32.163208 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 289:406(117) ack 1251 win 251 <nop,nop,timestamp 7589201 1355739382>
20:12:32.171213 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1251:1336(85) ack 406 win 122 <nop,nop,timestamp 1355739392 7589201>
20:12:32.186214 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 406:752(346) ack 1336 win 251 <nop,nop,timestamp 7589207 1355739392>
20:12:32.226172 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 752 win 130 <nop,nop,timestamp 1355739447 7589207>
20:12:32.228869 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1336:1554(218) ack 752 win 130 <nop,nop,timestamp 1355739449 7589207>
20:12:32.232552 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 752:789(37) ack 1554 win 270 <nop,nop,timestamp 7589218 1355739449>
20:12:32.232613 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 789 win 130 <nop,nop,timestamp 1355739453 7589218>
20:12:32.232795 IP 10.18.65.39.47552 > 10.108.90.237.8080: F 789:789(0) ack 1554 win 270 <nop,nop,timestamp 7589218 1355739449>
20:12:32.233915 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1554:1591(37) ack 790 win 130 <nop,nop,timestamp 1355739454 7589218>
20:12:32.234091 IP 10.108.90.237.8080 > 10.18.65.39.47552: F 1591:1591(0) ack 790 win 130 <nop,nop,timestamp 1355739454 7589218>
20:12:32.234515 IP 10.18.65.39.47552 > 10.108.90.237.8080: R 1674805095:1674805095(0) win 0
20:12:32.234594 IP 10.18.65.39.47552 > 10.108.90.237.8080: R 1674805095:1674805095(0) win 0

怪事。 如果客户端不调用socket.close(),在客户端java进程结束的时候, 却是以正常的fin/ack结束连接。

(全文完)

HTTPS,SSL,加密解密杂谈

根据wikipedia上的定义,HTTPS其实就是把HTTP协议架在SSL/TLS协议之上。因此HTTPS的安全是依靠TLS协议来保障的。SSL协议是TLS协议的前身。它是一个早期由netscape公司开发的安全协议。 它的1.0版本没有公开发布过。在经历了SSL 2.0和3.0版本之后,IETF对其进行了标准化,此后称之为TLS协议。 TLS的1.0版本和SSL3.0的差别极其细微。 现在TLS已经发布了 1.0, 1.1 和 1.2三个版本。

HTTPS/TLS协议的主旨是在不安全的网络上建立安全的新到,主要防范的目标是“窃听”和“中间人攻击”。针对这两个目标,采取的有效手段是对数据加密传输,和身份认证。

为了进行身份认证,HTTPS使用了由国际电信联盟制定的X.509数字证书标准。因此依赖于证书认证机构(certificate authorities)对数字证书的认证。关于这一点,需要结合非对称加密相关的细节才能很好的理解。用户使用浏览器访问的站点需要下发自己的数字证书,由用户的浏览器对站点的证书进行认证。当认证失败的时候,大多数浏览器会弹出提示,用户可以选择离开或自行承担风险继续浏览。

TLS协议的原理是,在server和client之间传输的数据不是明文的,而是经过一种对称加密算法加密的。这个加密算法的密钥则通过一个非对称加密算法来交换。在数据交换之前需要有一个握手阶段。 握手阶段会交换双方支持的协议版本,加密算法,并最终确定本次数据传输会话中将要使用的协议版本号,加密算法等。此外在握手阶段还会使用非对称加密算法交换一个密钥,用于本次会话中数据传输时对数据做对称加密。 其结果是,对称加密的密钥是短期临时的(每个session重新生成),而非对称加密算法的公钥/私钥对则是长期的。这么做的原因是出于性能的考量。非对称加密算法通常加解密都非常消耗系统资源。这么一来就解决了数据安全传输的问题。剩下的问题就是身份认证。

TLS协议工作在HTTP协议的下层,TCP协议的上层。它会将所有的数据包进行加密然后再传输。
继续阅读“HTTPS,SSL,加密解密杂谈”