竭诚为您提供优质文档/双击可除ssl握手协议报文头
篇一:ssl握手协议
篇二:第二章.对ssl握手协议的研究
第一章.对ssl的基本概念和框架的介绍
第二章.对ssl握手协议的研究(part-1)
第三章.对ssl握手协议的研究(part-2)
第四章.对ssl握手协议细节和实现的介绍
第五章.对ssl记录协议细节和实现的介绍
第六章.对ssl的安全性分析
第七章.举例一种将usbkey融入javajsse框架的解决方案client处理和回应serverhello阶段
客户端收到服务器发过来的那些消息,要做的是验证服务器证书,发送自己的证书(如果双向认证),发送计算出的预主密码,发送证书验证消息。
收到serverhello
在serverhello阶段连续的发了多个消息,最先发出的
是serverhello,client收到后将ssl会话id,服务器端的一个随机数,协商出的ssl协议版本号以及密钥套件放到会话缓存中。
收到servercertificates
接下来收到的应该是server端的证书消息了,取出所有的消息,最头上的是server证书,最末端的ca根证书。在sunjdkjsse中实现的ssl是这样处理的:
从sslcontex中取出trustmanager,如果用过javassl 编程的同学应该知道,可以自己实现x509trustmanager和x509keymanager两个接口来定制对证书的验证,sunjdk中就是调用这个trustmanager的验证方法来验证证书(在解决浏览器检测到证书是自签名的时候跳出警告框的问题就
是可以自己实现这个trustmanager来让浏览器不跳出警告框)。
jdk当然也有默认的证书验证实现,就是验证签名有效性,验证证书是否过期等。证书签名的有效性验证是在取证书链中某证书中的公钥验证前一个证书的签名,这样第一个证书就是用第二个证书的公钥来验证,那有人可能会问最后的根ca的证书谁来验证?根ca的证书是自签名的,就是自己给自己签名,没人管的了,jdk中某个文件中有存储一堆可信任的证书发行机构的证书列表,如果你的根ca在那个列表中并对比后确实是那个根ca的证书那就ok,验证通过,
这个可信任的机构也可以自己实现那个trustmanager来添加设置。
收到serverkeyexchange消息
Rsa方式密钥交换消息则把消息中的加密用公钥放入会话缓存中,作为客户端这边握手阶段的写密钥而不是用服务器证书中的公钥。
dh方式的消息就把消息中的p,g,ys三个参数记录下来,有这些client端就可以计算出pre-master了,只要回头再把自己这边的yc参数发过去,server端就也能计算出相同的pre-maseter了。
收到servercerttificatsRequest消息
将消息中的证书类型列表和可信任证书发行机构列表
保存下来,可在后面发送客户端证书时候拿来筛选证书用。
收到serverhellodone消息
收到这个消息后client端开始向server发消息了
发送clientcertificates消息
如果是server端要求客户端认证就会发这个消息,否则不发。客户端可能会有多个证书,在jsse里头多个客户端证书存储在keystore里头,选哪个发过去呢?这时候要用到server端之前发的certrequest消息中的支持的证书类型列表和信任的根ca列表,满足这个两个条件的第一个证书链(ssl握手协议报文头)就会被选中作为客户端证书。
发送clientkeyexchange消息
若是Rsa方式密钥交换,则产生一个48位随机数作为pre-master并用服务器公钥加密后发出去
若是dh方式的密钥交换,则根据sever的g,p,ys,产生xa和yc,xa和ys能计算出pre-master,把产生的yc放入消息中发给
server,这样server用它的xb和yc也能计算出
pre-master了。
计算出预主密码后就顺便把主密码(mastersecret)给算出来了。算出主密码就把对称密钥产生出来了。
发送certificateverify消息
这个消息是可选的,只有在客户端发送了自己证书到服务器端,这个消息才需要发送。发这个消息的目的是让服务器验证发消息的客户端和客户端证书的真实所有者。这个消息中要包含一个签名,签名里头内容就是从clienthello开始到目前为止所有握手消息(不包括本消息)的摘要,主密码,若是Rsa方式则要把这些内容分别用md5和sha1计算一遍,两种摘要算法算得的摘要拼接起来用客户端证书中公钥对应的私钥加密就获得了签名。到时候服务器端会用收到的证书中的公钥来验证签名。
发送changecipherspec消息
发送这个消息,然后把session的写密钥设置成计算得