加密
网络安全是一个非常重要的问题。目前绝大多数的网络站点都是通过https来保证web站点的安全可靠,提到https就想到了 TLS/SSL。下面介绍一下ssl和tls的区别和历史。
SSL和TLS的区别和历史
- SSL 1.0 未公开发布,因为存在严重的安全性漏洞。
- SSL 2.0 1995年2月发布,因存在安全漏洞。在2011年被RFC 6176禁止。
- SSL 3.0 1996年诞生,代表的是SSL该协议的完全重新设计,但是3.0也在2015年被RFC 2246 禁止。
- TLS 1.0 作为SSL 的升级版本于1999年首次定义。同时应微软要求,改名为TLS。
- TLS 1.1 2006年诞生。
- TLS 1.2 2008年发版。
- TLS 1.3 2018年发版。
TLS安全密码套件
其套件大致分为4个组成部分:
密钥交换
ECDHE这个是一个椭圆曲线加密算法。这个算法解决的是怎样让浏览器和服务端各自独立生成一套相同的密钥。
- 客户端浏览器随机生成一个值Ra,计算Pa(x,y) = Ra*Q(x,y),Q(x,y)为全世界公认的某个椭圆曲线算法的基点。将Pa(x,y)发送至服务器。
- 服务器随机生成一个值Rb,计算 Pb(x,y) = Rb * Q(x,y)。将Pb(x,y)发送到客户端浏览器。
- 客户端计算Sa(x,y) = Ra * Pb(x,y),服务器计算Sb(x,y)=Rb*Pa(x,y)
- 算法保证了Sa=Sb=S, 提取其中的S的x向量作为密钥。
举个例子吧~~
假设约定算法参数:模数97,基数3。
张三自己随机出来的私钥是6,李四自己随机出来的私钥是21。
p = 97
g = 3
a = 6 , b = 21
A = (g**a)%p
B = (g**b)%p
(B ** a) % p = 47
(A ** b) % p = 47
最终 47 张三,李四都得到了。当然实际中的模数足够大 ,通常至少300位以上。
密钥交换也可以由RSA来做,这是一种古老的做法,即客户端利用证书中的公钥去加密预主密钥,服务端再去用私钥解密
身份验证(证书验证)
RSA的核心涉及的是公钥和私钥的概念。也就是用公钥加密后的数据只能私钥解,用私钥加密的数据只能公钥解开。
- 客户端发起请求,服务端首先回复自己的公钥到客户端。
- 客户端使用随机数算法,生成一个密钥S,使用服务端发来的公钥进行加密,生成C,再将C发到服务端。
- 服务端收到C后,用自己的私钥进行解密,得到S。
- 算法使得服务端和客户端都得到了S,而S就是 密钥(预主密钥)
对称加密算法,强度,分组
AES算法是高级加密标准,也是最常见的对称加密算法,对称加密的特点即为加密解密需要相同的密钥。具体的加密过程就不详细介绍了。需要提出的分组,GCM模式是一种新的分组模式,可以提升多核CPU的加解密速度。
签名hash算法
SHA256 是一个摘要算法,是为了将不定长度的字符串,生成一个更短的固定长度的摘要。
HTTP 与 TLS
下图中站点的维护人就是证书订阅人,首先需要申请一个证书,需要在登记机构登记自己的信息。然后由CA机构签发证书。CA机构生成一对密钥,其中公钥在CA中保存。
1.客户端请求站点,Web服务器将自己的公钥证书发给浏览器,而浏览器验证是否合法。
2.浏览器需要检验证书是否合法过期。CA机构会将所有的过期的证书放到CRL服务器上,而这些证书会形成一个链条,所以在CRL上查是性能很差的。所以CA机构推出OCSP响应程序,浏览器可以在OCSP上查取某一证书是否过期。但其实这样的机制还是性能太差。所以Nginx 上有 OCSP 的开关,开启后,由Nginx去主动查询。
证书类型
域名验证(domain validated,DV) 证书
这种证书是最便宜的,申请后可立即颁发。
- 审核的内容:域名管理权限
- 一般用途:个人站点,登陆等单纯的https加密需求。
组织验证(organization validated, OV) 证书
这种证书一般贵。申请后几天后颁发。
- 审核的内容:域名管理权限,企业名称,地址,电话等信息的真实性。
- 一般用途:企业网站
扩展验证(extend validation, EV)证书
这种证书比较贵,签发需要一个礼拜。
- 审核内容:除上述需要验证的内容外,还需要验证第三方数据库审查,律师证明等。
-
一般用途:企业官网,电子商务网站,P2P互联网金融,正式的大型网站。
EV证书如图所示,有附加的地址栏,组织,公司名称。
证书链
首先打开证书查看器
基本上所有的证书层次结构都是这样的,最上面是根证书。二级证书签发机构是DigCert。
- 根证书的验证是十分谨慎的,大部分浏览器都使用的是操作系统的根证书。少部分的如firefox的根证书是自己维护的,也就是说其实根证书是没必要发给客户端的。只需要将两个证书发给客户端就可以了。
如下图:
由上图可以看到,在交互过程中.只有两个证书被交给了客户端,一个是guthubapp.com , 一个是DigCert 二级证书。浏览器会自动验证证书有效性。
https过程
数字认证机构(CA)用自己的私钥加密了web站点管理员的公钥和身份信息,而CA的公钥是存在于客户端浏览器和客户端操作系统中的。web站点用加密后的证书证明自己,而浏览器端用自己的CA公钥验证该网站的真实性。
注意:下图有些老,是还用RSA加密预主密钥的方式,而用证书私钥解密预主密钥的方式是向前不安全的,即证书私钥一旦丢失,就可能造成之前已加密传输数据的安全性,新的都是用DECH的,也就是多了一步server key exchange
接下来通过抓包的方式演示一下整个https的握手流程。
如下图
1. tcp 三次握手,该过程略。
2. Client Hello
- 该阶段,客户端发送Client Hello 开始TLS 通信,报文中包含客户端支持的TLS 版本(都没人支持SSL了.....),加密组件列表(Cipher suites),随机数,Session Ticket (这个之后在Nginx 与 https 文中讲解)
3. Server Hello
- 该报文同样包含一些TLS版本,服务端从客户端加密组件筛选出匹配的。选择加密套件中的Cipher suite。压缩算法等等。(这里选择的加密套件规定了后续所有加密的算法,如密钥交换的算法,之后对称加密的算法,摘要验证的算法,PRF(伪随机数函数))
4.Server Certificate
- 可以看到服务端将自己的两个证书发送过来,一个是baidu的,一个是二级证书GlobalSign。这里服务端是不需要发送根证书的,因为根证书,客户端有。客户端收到证书后会进行证书链的校验,有包括离线的CRL和在线的OCSP方式。证书的有效期expiry date。以及证书的域名是否和当前访问的域名所匹配。
5.Server Key Exchange
- 这里就是 ECDHE 密钥交换。服务器将自己的ECDHE 数以及相应的椭圆曲线参数 传递给客户端。
对于RSA而言,Certificate Message 中已经包含足够的信息可以,而Client key Excahnge 可以使用这些信息进行加密预主密钥,但是对于DH 这类算法而言,Certificate Message 中只包含部分信息,剩余的就在Server Key Excahnge 中。也就是说采用DH算法,证书只是用来验证身份的,而非是用来提取公钥然后做加密预主密钥的。
若单纯的使用RSA算法,RSA即用作验证服务器身份,又用来做加密预主密钥,RSA使用证书中的公钥加密。但是这样向前不安全
DH算法所以和RSA算法一起使用,RSA做验证服务器身份,DH算法专门加密预主密钥,使用DH算法向前安全。
6.Server Hello Done
- 服务端通知客户端,信息发送结束。
7.Client Key Exchange
- 因本例使用了DH算法,所以不需要RSA了。这里的预主密钥就有DH算法来解决了,如上图。当然这个预主密钥是为后来的对称加密做准备。
8.Change Cipher Spec
- 本过程的是告诉服务端,好了。现在开始后续的通信都采用协商后的通信密钥进行对称加密吧。(图在过程7中)
9. Encrypted Handshake Message
- 结合之前的所有通信参数的hash值与其他相关的数据,发送给服务器端用做数据与握手的验证。验证对端是否计算了相同的参数。(图在过程7中)
10. Change Cipher Spec
- 服务端也发送 Change Cipher Spec,意思同意开始对称加密通信。
11. Encrypted HandShake Message
- 服务端也结合当前的通信参数生成一段数据,并采用协商密钥 session secret 与算法加密,发送至客户端。
参考文章:https://blog.csdn.net/mrpre/article/details/78025940
https://github.com/geektime-geekbang/geektime-nginx/blob/master/Nginx%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86100%E8%AE%B2-%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86%E8%AF%BE%E4%BB%B6.pdf
https://blog.csdn.net/andylau00j/article/details/54583769
这里推荐的文章:
HTTPS背后的加密算法
为什么强烈建议使用ECC证书