-
Notifications
You must be signed in to change notification settings - Fork 0
Description
前言
一般来说,https就是基于ssl安全管道的http。其英文含义为Hyper Text Transfer Protocol over Secure Socket Layer。也就是这个意思。
现在,这个安全的管道的规范一般叫TLS(transport layer security),也就是传输安全层的意思。这个规范是后来被IETF(The internet Engineering Task Force)规范定义的。其实一开始ssl是由网景公司率先使用的,后来被IETF采用规范。至少可以说明,这是个经过历史考验的东西,事实上, https也确实解决了http无法解决的安全问题。
https意义
https解决了以下问题:
- 保证数据隐私
- 防止数据篡改
- 验证双方身份(或对方身份)
为什么http无法解决以上三个问题:可以有很多方式解决各种各样安全问题,但是http对于中间人这块,确实毫无头绪。任何在网络上传输的内容被劫持,对http来说是无感知的。为了防止数据被篡改,很多api采用数字签名校验方式,但是这种前提是基于双方是服务器的情况下,可以各自保存一对私钥做对称加密校验。一旦涉及到浏览器互联网,那么私钥就必须在网络上传输,对于web应用这种请求,无法保证所有客户端都能持有私钥。
这里简要说明下一般情况数字签名的过程,与https无关:
通常就是对校验内容进行操作生成摘要,然后双方在持有seret_key的情况下通过约定好的加密过程生成签名。任何一方可以通过逆向解密校验内容的完整性。
具体应用场景可以参考微信支付的签名过程:
微信支付签名算法
虽然说对称加密无法做到,但是非对称加密却可以避免上面的问题,这也正是https的前提。非对称加密让https安全成为可能,如果你想到利用非对称加密保证安全性的最好方案,那么极有可能就是https的这一套。
非对称加密:
双方分别持有两个秘钥分别是公钥和私钥,公钥加密内容必须用私钥解,私钥加密内容必须通过公钥解。算法支持:Rsa算法
https的单向认证和双向认证
https有两种校验模式,一种是单向认证,一种是双向认证。一般我们平时访问https网站时候都会用到单向认证,所以市面上大多数讨论是针对单向认证。两者区别实际上是,一方持有证书的验证方式还是双方均持有证书的认证方式。比如有时候,一些支付,网盾,需要安装客户端安全控件,会给客户端安装ca证书,实际上就是双向认证。而单向认证只要验证服务器合法即可。
单向认证握手过程
- 客户端访问https网站,生成一个随机数C,发送hello请求,带上随机数和客户端支持的加密算法
- 服务器加载自己的证书信息,生成随机数S,返回随机数S,证书信息带公钥和支持的加密算法
- 客户端拿到服务器证书,首先校验证书的有效性,正确性。有问题提示信息不安全
- 客户端生成私有随机数PreMaster, 并且通过证书公钥加密PreMaster
- 服务器通过私钥解密PreMaster获得私有随机数
- 服务器和客户端结合随机数C,随机数S,私有随机送PreMaster,通过上面协商好的加密算法生成对称加密私有密钥
- 服务端将本次握手涉及到的内容通过生成哈希,用对称加密私有秘钥加密哈希传输客户端
- 客户端将本次握手涉及到内容通过生成哈希,用私钥解密服务器内容得到服务器哈希,比对哈希
- 结束握手,后续通过对称加密传输报文
以上即使https的握手过程,那么问题来了,为什么https要进行这么复杂的握手操作。为什么我们不直接通过最简单的非对称加密传输报文。我想到的原因有:
- rsa算法原理限定了加密的报文必须受限于公钥长度(参考rsa算法原理)
- rsa算法加密涉及到复杂的计算,性能方面服务器端消耗巨大
- ca证书校验过程保证了证书的合法性,使得中间人无法通过伪造证书的形式进行攻击
当然,如果聪明的同学肯定会继续想,对于1确实没办法,但是假设没有1的限制,2似乎有反驳的理由,因为这就涉及到,难道https能保持安全管道吗,因为对于每一次https请求,是否都进行握手,如果是,这个性能似乎并没有太大影响。答案确实是对于浏览器支持上,https握手过程确实是由状态保留的,尽管http本身并无状态保持可言。但是,浏览器端确实保存有之前的对称加密秘钥session_id, 这个id由服务器端维护的一个索引值对于本次握手过程的对称加密私钥并且在第一次握手中会返回给浏览器。后续的请求实际上可以节省很多计算。
对于第3点,也就是后续要讨论的,证书校验过程实际上保证对方身份并且中间人无法伪造证书的方式进行攻击。
证书校验过程
证书主要包含哪些内容呢?一般来说,主要需要关注的内容如下:
- 证书签名:Signature
- 证书签名使用的算法
- 证书颁发机构
- 过期时间
- 证书公钥
- 其他不重要内容
证书签名一般通过将证书内容生成hash后,对称加密算法加密,颁发机构使用公钥再次加密生成签名。因为浏览器已经包含了所有信任的证书机构,浏览器就可以通过同样的颁发生成hash,使用颁发者公钥解密签名,比对hash的合法性。
浏览器会验证证书的以下几个方面:
- 因为浏览器内置了受信任的颁发机构,所以检查是否是收信任的机构颁发的。过程包含了上面的签名校验。
- 检查证书是否被吊销
- 检查证书域名和网站域名是否一致
- 检查证书师傅过期
ie浏览器还会到欺诈网址查询网址的正确性。
证书校验的意义
证书校验过程的意义在于,单纯使用非对称加密是无法避免中间人攻击的。我们假设只进行非对称加密,客户端持有公钥,服务器持有私钥。中间人可以获得服务器的公钥,同时自己可以准备自己的私钥和公钥。收到服务器的信息时候,可以使用服务器的公钥解密,然后用自己私钥加密,只需要给客户端发送自己的公钥,客户端就无法判断请求对方是不是合法的�。
所以,通常需要一个有公信的机构去维护域名和证书的对应关系。证书校验过程就是要验证对方身份。一般来说,证书可能有多个层级,根目录公信力最强,每一层的证书需要上一层的公钥去验证签名。服务器返回的证书是一个证书链的关系,证书中的根目录只要是浏览器内置合法机构颁发,即是安全的。
