HTTPS相较于HTTP,可以防止中间人进行窃听、篡改信息和冒充服务,以下是https的相关原理
1.https最终采取的安全通信方法是采用对称加密(对称加密速度快性能高):

那么怎么样将密钥安全得给到客户端呢?
2.非对称加密,解决单向对称密钥的传输问题:
非对称加密即加解密双方使用不同的密钥,一把作为公钥,可以公开的,一把作为私钥,不能公开,公钥加密的密文只有私钥可以解密,私钥加密的内容,也只有公钥可以解密。
注:私钥加密其实这个说法其实并不严谨,准确的说私钥加密应该叫私钥签名,因为私密加密的信息公钥是可以解密的,而公钥是公开的,任何人都可以拿到,用公钥解密叫做验签
这样的话对于 server 来说,保管好私钥,发布公钥给其他 client, 其他 client 只要把对称加密的密钥加密传给 server 即可,如此一来由于公钥加密只有私钥能解密,而私钥只有 server 有,所以能保证 client 向 server 传输是安全的,server 解密后即可拿到对称加密密钥,这样交换了密钥之后就可以用对称加密密钥通信了。
但是问题又来了, server 怎么把公钥安全地传输给 client 呢。如果直接传公钥,也会存在被中间人调包的风险。
3.数字证书,解决公钥传输信任问题:
如何解决公钥传输问题呢,从现实生活中的场景找答案,员工入职时,企业一般会要求提供学历证明,显然不是什么阿猫阿狗的本本都可称为学历,这个学历必须由第三方权威机构(Certificate Authority,简称 CA)即教育部颁发,同理,server 也可以向 CA 申请证书,在证书中附上公钥,然后将证书传给 client,证书由站点管理者向 CA 申请,申请的时候会提交 DNS 主机名等信息,CA 会根据这些信息生成证书:

这样当 client 拿到证书后,就可以获得证书上的公钥,再用此公钥加密对称加密密钥传给 server 即可,看起来确实很完美,不过在这里大家要考虑两个问题:
1.如何验证证书的真实性,如何防止证书被篡改:
想象一下上文中我们提到的学历,企业如何认定你提供的学历证书是真是假呢,答案是用学历编号,企业拿到证书后用学历编号在学信网上一查就知道证书真伪了,学历编号其实就是我们常说的数字签名,可以防止证书造假。

2.客户端拿到证书后也用同样的摘要算法对证书明文计算摘要,两者一笔对就可以发现报文是否被篡改了,那为啥要用第三方权威机构(Certificate Authority,简称 CA)私钥对摘要加密呢,因为摘要算法是公开的,中间人可以替换掉证书明文,再根据证书上的摘要算法计算出摘要后把证书上的摘要也给替换掉!这样 client 拿到证书后计算摘要发现一样,误以为此证书是合法就中招了。所以必须要用 CA 的私钥给摘要进行加密生成签名,这样的话 client 得用 CA 的公钥来给签名解密,拿到的才是未经篡改合法的摘要(私钥签名,公钥才能解密)server 将证书传给 client 后,client 的验签过程如下(公钥解密叫做验签):

这样的话,由于只有 CA 的公钥才能解密签名,如果客户端收到一个假的证书,使用 CA 的公钥是无法解密的,如果客户端收到了真的证书,但证书上的内容被篡改了,摘要比对不成功的话,客户端也会认定此证书非法。
细心的你一定发现了问题,CA 公钥如何安全地传输到 client ?如果还是从 server 传输到 client,依然无法解决公钥被调包的风险,实际上此公钥是存在于 CA 证书上,而此证书(也称 Root CA 证书)被操作系统信任,内置在操作系统上的,无需传输。server 传输 CA 颁发的证书,客户中收到证书后使用内置 CA 证书中的公钥来解密签名,验签即可,这样的话就解决了公钥传输过程中被调包的风险。
3.但任何站点都可以向第三方权威机构申请证书,中间人也不例外。正常站点和中间人都可以向 CA 申请证书,获得认证的证书由于都是 CA 颁发的,所以都是合法的,那么此时中间人是否可以在传输过程中将正常站点发给 client 的证书替换成自己的证书呢?
答案是不行,因为客户端除了通过验签的方式验证证书是否合法之外,还需要验证证书上的域名与自己的请求域名是否一致,中间人中途虽然可以替换自己向 CA 申请的合法证书,但此证书中的域名与 client 请求的域名不一致,client 会认定为不通过!
4.如何抓取HTTPS传递的明文信息?
上面的证书调包给了我们一种思路,什么思路?大家想想, HTTPS 既然是加密的, charles 这些「中间人」为啥能抓到明文的包呢,其实就是用了证书调包这一手法,想想看,在用 charles 抓 HTTPS 的包之前我们先要做什么,当然是安装 charles 的证书,这个证书里有 charles 的公钥,这样的话 charles 就可以将 server 传给 client 的证书调包成自己的证书,client 拿到后就可以用你安装的 charles 证书来验签等,验证通过之后就会用 charles 证书中的公钥来加密对称密钥了,整个流程如下:

由此可知,charles 这些中间人能抓取 HTTPS 包的前提是信任它们的 CA 证书,然后就可以通过替换证书的方式进行瞒天过海,所以我们千万不要随便信任第三方的证书,避免安全风险。
一些相关概念:
-
证书信任链:
前文说了,我们可以向 CA 申请证书,但全世界的顶级 CA(Root CA) 就那么几个,每天都有很多人要向它申请证书,它也忙不过来啊,怎么办呢,想想看在一个公司里如果大家都找 CEO 办事,他是不是要疯了,那他能怎么办?授权,他会把权力交给 CTO,CFO 等,这样你们只要把 CTO 之类的就行了,CTO 如果也忙不过来呢,继续往下授权啊。
image.png
如果站点申请的是二级 CA 颁发的证书,client 收到之后会如何验证这个证书呢,实际上 service 传了传给二级 CA 的证书外,还会把证书信任链也一起传给客户端,这样客户端会按如下步骤进行验证:
1.浏览器就使用信任的根证书(根公钥)解析证书链的根证书得到一级证书的公钥+摘要验签
2.拿一级证书的公钥解密一级证书,拿到二级证书的公钥和摘要验签
3.再然后拿二级证书的公钥解密 server 传过来的二级证书,得到服务器的公钥和摘要验签,验证过程就结束了
网友评论