HTTPS是什么?
HTTPS是并不是一个新的协议,而是HTTP+SSL/TLS,用来保证信息传递的安全.
学习HTTPS,就是学习https解决了什么问题,以及他是怎么解决这个问题的。HTTPS解决了HTTPS协议通信不安全的问题,为什么说HTTP通信不安全呢?
因为在实际的网络中,我们以为我们的通信是
A对B的
但是实际上我们的通信可能是这样的
A跟B的通信有可能会被C进行监听,而HTTP是明文传递的,A传给B的每一句话都能被C看到,甚至进行篡改,所以很有可能会发生这样的事情
可以看到,假如我们的信息被第三方拦截到了并且进行了篡改,那么问题就很严重了,特别是假如我们传递的消息里面存在一些敏感信息比如银行账户密码等等就很容易造成财产损失
那么我们假设自己的信息一定是在被监听到的,那么怎么才能避免自己跟别人通话的内容被别人知道呢?
我们很显然可以想到通过加密来解决这个问题
怎么进行加解密呢?以前的时候加密方式依赖于加密方式,而现在的加密方式依赖于密钥
比如
ABC,我们的加密方式是每位前移一位,那么加密后就变成了BCA,解密只需要倒退一位就好了,但是破解也很简单,而现在的加密方式是我们约定好一种加密方式,这种加密方式地球人都知道,但是他不仅仅需要我们需要加密的内容,还需要一个密钥,解密的时候也需要这样一个密钥,类似于
密钥A=xxxxxx
加密函数func
加密内容content
密文==func(content,密钥A)
content=func(密文,密钥)
这就好像是有一个保险箱子,所有的人都知道这个保险箱怎么做,但是最后保险箱的钥匙只有自己有,每个保险箱的钥匙也是不一样的
但是在上面的公式中,加密的时候使用的是密钥A,而在解密的时候写的是密钥,这是为什么呢?
因为现在世界里面有两种加密方式
对称加密
非对称加密
对称加密是指加密的密钥跟解密的密钥都是一个,而非对称加密则会生成两个密钥,用密钥A加密的密文必须要密钥B才能解密,同样用密钥B加密的密文必须要密钥A才能解密
为什么需要两种加密方式呢?
对称加密是先于非对称加密出来的,就像我们把东西缩进一个保险箱,打开保险箱把东西放进去,与打开保险箱把东西取出来是一个钥匙,而在通信之中对应的就是密钥了。
看起来好像完美无瑕了,但是实际上存在一个问题,那就是,怎么才能把密钥给对方呢???
加入A要跟B使用对称加密进行通信,第一步就是需要双方都知道一个密钥,而这个密钥的传递本身又是一个问题,假如在传递密钥的过程中被黑客拦截了,知道了这个密钥,那么加密也就是没有意义了,而如果使用密文传递密钥,这就是变成了先有鸡还是先有蛋的问题了。所以我们需要非对称加密
怎么使用非对称加密进行通信
- A通过非对称加密生成两个密钥,一个用来加密的公钥,一个用来解密的私钥,然后A把自己的公钥告诉了B,B通过公钥加密以后发送给了A,A再用私钥进行解密,即使黑客在这之中拦截到了B发给A的信息,因为没有私钥,所以他也不知道这条信息代表什么意思(不过实际上,因为非对称加密比对称加密要慢很多很多,一般是用来传递我们在上面所说的对称加密的密钥,这样就可以避免被黑客知道对称加密的密钥了)
不过在上面我们其实也可以看到一些问题,至少有两个问题
- 怎么才能保证A给B的公钥是正确的呢?也就是说公钥的传递没有被黑客篡改?
- 怎么才能保证A收到的B的信息是正确的呢?加上黑客用公钥篡改了B的话,A的解密不就出现问题了吗?
我们先来看第二个问题
你应该听过MD5算法,这是一种摘要算法,也就是可以把一段内容最后变成一段字符串,这种转变是单向的,假如被别人修改了这段文字中的任何一个字符,最终得到的字符串也会变得非常的不一样。
所以我们可以对原文生成摘要,把摘要也带过去。这样在收到内容以后跟摘要进行一次对比,那么就知道了我们的内容是不是被篡改了。然而,假如黑客连摘要也生成了一份呢?这个时候我们应该怎么办?那就继续加密呗,再用非对称加密加密摘要一次。
当然这又回到了我们的第一个问题,怎么才能保证我们的公钥是正确的?
实际上,假如我们的互联网世界只有A跟B,那么保证正确已经没有可能了,除非A跟B亲自见一面,像防怪盗基德一样捏捏脸,把公钥背下来再用小纸条记下来,这次通信才有可能安全。
而在互联网中,我们可以借助第三方公证处的力量,A在生成公钥以后,不仅仅给B一份,还在第三方进行一次认证,把这个公钥给第三方,B拿到A传递过来的公钥以后去第三方验证一下,那么不就OK了吗?
不过这里我们就会产生另外一个疑问,假如我们去第三方公证处进行验证的时候被黑客拦截了怎么办???我们去了一个假的公证处,最后把假的密钥判断为真的密钥了。这不是坑大了???
要解决这个问题,则有牵涉到了另外几个点
- 摘要算法
- 数字证书于数字签名
- 自签名证书与根证书
- 证书链
我们要解决的问题是跟通信有关的问题,而我们最后要解决跟通信有关的问题却不能完全依赖通信,根据非对称算法,公钥加密必须需要私钥来解密,那么私钥加密就必须要用公钥来解密,我们可以在操作系统中内置一份公钥用来进行解密,解密的内容在哪里呢?解密公证处的信息。接下来我们说一下这个证处如何生成。
首先所有的操作系统在出厂的时候都会安装一个根证书,现在我们先不管证书是啥只知道里面有公钥,这个我们可以认为是最顶级的机构(我们称为CA Certificate Authority,证书认证机构)的公钥,他一定是正确的,如果不正确,那跟通信也没多大的关系了,我们必须要认为他是正确的,然后才能继续走下去。这个时候假如某个服务端想去提交自己的公钥,那么就去发放了计算机里面的证书的机构进行验证,这个时候机构将服务端的公钥以及一些其他的信息,比如颁发者有效时间等等生成摘要,随后再用自己(根证书对应的机构)的私钥加密这段摘要,这个操作称为签名*,最后生成一个证书返回给服务端,服务端将这个证书给浏览器,此时我们判断一下,假如黑客修改了证书的内容,也就是伪造了CA,会发生什么样子的事情?
因为黑客不知道CA(公证处)的私钥,所以最后生成的摘要被浏览器用系统中的公钥解密后得到的摘要与证书上的内容的摘要对不上,那么就可以判断出来此时已经被伪造了,所以我们的通信必然是安全的。
如果黑客修改了根证书的内容,那么这个漏洞已经无法在通信阶段进行验证解决了
此外,实际上,全世界这么多个需要用HTTPS的网站,需要申请证书,不可能每个都去根证书的发放机构进行申请,这个时候就会有一级CA跟二级CA这些,他们也会有自己的私钥。
假如一个服务器向一级CA进行证书申请,怎么才能进行验证呢?答案是一级CA本身就是通过了根证书的CA的验证,怎么做呢?一样使用数字证书,也就是一级CA向根证书发放的CA进行审核的,根证书的CA里面也给他一个证书,里面包括了对应的信息,这些信息生成了摘要并且使用私钥加密完成签名,而一级CA发放给了服务端的证书里面,就会有对应的证书,在浏览器收到证书以后,判断了出来它是一个一级CA的证书,使用根证书的公钥对一级证书的摘要进行解密比对,如果正确,就获得了一级证书的公钥,再用一级证书的公钥来验证服务器的证书,依次类推到二级三级CA,这也就是证书链,证书链是在一开始请求的时候就返回的。因此我们的通信始终都是安全的。
在这里我们也可以看到
- 我们判断二级证书是否正确,是因为有一级证书的公钥做验证
- 判断一级证书是否被篡改,是因为有根证书进行判断
- 而根证书没有办法让别人来办他来验证自己是不是正确的了,不然就走不下去了,他只能自己说自己是正确的,也就是自己给自己进行签名,这样的证书就是自签名证书
最后我们来总结一下HTTPS的通信过程
- 服务端向CA机构申请数字证书,里面包含自己的公钥以及证书链,
- 服务端将自己的证书交给浏览器
- 浏览器对证书链进行逐层验证,最终判断获得服务端的公钥
- 浏览器生成对称加密算法的秘钥,用服务器的公钥加密发送给服务端,
- 服务端使用自己的私钥进行解密最终获取到对称加密的公钥
- 服务器与浏览器使用秘钥进行加密通信
文章参考
其实一开始写作这篇文章之前想了解https的时候是先看的掘金的这篇文章,不过这篇文章里面没有提到最后证书链本身不安全的情况,只是简单的提到了第三方验证,随后学习了极客时间课程的https部分,这个倒是讲的非常的详实不过最后也是在评论区里面找到了关于证书链的讨论,最终解决了自己的疑惑,而码农这本书则是后来的时候翻到的了,最后提到了证书的验证问题,不过跟极客时间一样。。。大概以为我们都懂了,能想到证书链这块怎么做验证,就带过去了,稍微有点难受,最终才决定再写一篇的HTTPS,不求追求过多的细节,只求能够解答最后的疑惑