人们越来越意识到安全的重要,不只是人身安全,还包括我们个人信息的隐私安全。在互联网时代,想要保障我的信息安全,我们就要保证我们的系统安全和网络安全,于是HTTPS应运而生了。
HTTPS其实就是HTTP+SSL,SSL是由网景公司设计的用于对HTTP传输数据进行加密的协议,相比于HTTP的明文传输,HTTPS是加密的,所以更安全,但是因为建立连接需要更多的会话,所以效率稍低。
对比一下HTTP和HTTPS的工作过程:
这两张图都是网上down下来的啊,没有自己画,很明显能看出来HTTP和HTTPS的优缺点,一个效率高,一个更安全。
第一张图就是HTTP建立连接的过程,通常HTTP请求是使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议来传输数据;
HTTP的握手过程也就是TCP的握手过程,使用三次TCP握手确认建立一个HTTP连接。
TCP的三次握手
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
第二张图就是HTTPS的连接过程,HTTPS协议在HTTP的基础上加入了SSL协议,SSL依靠证书来验证身份;验证身份可以是只验证服务器的身份,也可以是双方互相验证身份;取决于双方是否携带证书。
SSL握手过程
- 首先,客户端先向服务器发出加密通信的请求,这被叫做Client Hello请求。
在这一步,客户端主要向服务器提供以下信息。
- 支持的协议版本,比如SSL 1.0版。
- 一个客户端生成的随机数,稍后用于生成"对话密钥"。
- 支持的加密方法,比如RSA公钥加密。
- 支持的压缩方法。
- 服务器确定本次通信采用的版本和加密套件,并通过Server Hello消息通知给客户端。
在这一步,服务器主要向客户端提供以下信息。
- 确认使用的加密通信协议版本,比如SSL 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数,稍后用于生成"对话密钥"。
- 确认使用的加密方法,比如RSA公钥加密。
- 服务器证书。
- 客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。
- 一个随机数。该随机数用服务器公钥加密,防止被窃听。
- 客户端发送Change Cipher Spec消息,通知服务器后续报文将采用协商好的密钥和加密套件进行加密和MAC计算。
- 客户端计算已交互的握手消息(除Change Cipher Spec消息外所有已交互的消息)的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等),服务器利用同样的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,如果二者相同,且MAC值验证成功,则证明密钥和加密套件协商成功。
上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。
至于为什么一定要用三个随机数,来生成"会话密钥":
不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
premaster的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么premaster secret就有可能被猜出来,那么仅适用premaster secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上premaster secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。
- 服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。
- 服务器发送Change Cipher Spec消息,通知客户端后续报文将采用协商好的密钥和加密套件进行加密和MAC计算
- 服务器计算已交互的握手消息的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等),客户端利用同样的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,如果二者相同,且MAC值验证成功,则证明密钥和加密套件协商成功。
这样,HTTPS协议的SSL的四次握手就完成了,在这个过程中双方交换了随机数、验证了数字证书、协商了加密协议。
数字证书
数字证书颁发过程一般为:用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布。数字证书各不相同,每种证书可提供不同级别的可信度。可以从证书发行机构获得您自己的数字证书。
数字证书是一个电子文档,其中包含了持有者的信息、公钥以及证明该证书有效的数字签名。而数字证书以及相关的公钥管理和验证等技术组成了PKI(公钥基础设施)规范体系。一般来说,数字证书是由数字证书认证机构(Certificate authority,即CA)来负责签发和管理,并承担PKI体系中公钥合法性的检验责任;数字证书的类型有很多,而HTTPS使用的是SSL证书。
怎么来验证数字证书是由CA签发的,而不是第三方伪造的呢? 在回答这个问题前,我们需要先了解CA的组织结构。首先,CA组织结构中,最顶层的就是根CA,根CA下可以授权给多个二级CA,而二级CA又可以授权多个三级CA,所以CA的组织结构是一个树结构。对于SSL证书市场来说,主要被Symantec(旗下有VeriSign和GeoTrust)、Comodo SSL、Go Daddy 和 GlobalSign 瓜分。 了解了CA的组织结构后,来看看数字证书的签发流程:
将报文(就是持有者信息和公钥)按双方约定的HASH算法计算得到一个固定位数的摘要。在数学上保证:只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。
将该报文摘要值用发送者的私人密钥加密(对明文进行解密完全没问题,会得出一个不可读的“明文”),然后连同原报文一起发送给接收者,而“加密”后的报文即称数字签名。
接收方收到数字签名后,用同样的HASH算法对原报文计算出报文摘要值,然后与用发送者的公钥对数字签名进行解密(原先已经把签名加密了,再解密就能还原)得到的报文摘要值相比较。如相等则说明报文确实来自所称的发送者。
(由于只有拥有私钥的签名者能通过“解密”摘要生成签名,因此具有安全和不可抵赖性。)
那为什么是对报文摘要进行加密,而不是对原报文进行加密呢?这是因为RSA加解密非常耗时,被加密的报文越大,耗得时间越多,因此聪明的人类对其摘要进行加密,(因为报文摘要是要比原报文小得多),仍然能够起到同样的作用。这就是为什么多了个报文摘要。
看到这里我们对数字证书和HTTPS的连接有了基本的了解,假如我们现在要做证书验证(假如我们的证书是CA签发的),那么我们需要做以下操作:
- 对证书的内容做Hash得到H1;
- 从签发该证书的机构CA的数字证书中找到公钥(这个公钥是公开的,都可以获取),对我们的证书上数字签名进行解密,得到证书签名的Hash摘要H2;
- 对比H1和H2,如相等,则表示证书没有被篡改。
- 如何保证CA是受信任的,我们首先要知道证书都是一级一级签发的,而我们的申请下来的客户端证书是不能再签发新的证书,所以只要我们系统中装了受信任的CA自签名证书,那我们就能根据证书链一级一级向上验证,直到受信任的锚点证书。
如有错误之处,还请不吝赐教,谢谢!