00.https基本
名词解释
对称加解密
常用算法是AES,过程如下
A和B通信,双方都使用同一个密钥(比如123456)对数据进行加解密。
A先使用123456对数据“ Hello B”进行加密,然后传送给B,B再利用123456对收到的数据进行解密就可以得到原文“ Hello B ”
对称加解密的目的是为了保证消息的保密性。
非对称加解密
常用算法是RSA,过程如下
生成一对公钥和私钥,私钥自己持有藏到裤裆里藏好,公钥可以像小广告一样发给任何人
A持有B的公钥,B持有私钥,A首先利用B的公钥对消息“ Hello B ”进行加密然后发送给B,
B收到消息后利用藏在裤裆里的私钥进行解密得到“ Hello B ”
那B如果想给A发送消息咋办呢?
利用藏在裤裆里的私钥对“ Hello A ”进行加密然后发送给A,A收到消息后利用B的公钥进行解密得到“ Hello A ”,好像没问题是吧?
仔细琢磨下,公钥任何一个人都可以从B那里获取到,这样B用私钥加密的消息岂不是大家都能解密
所以非对称加解密的正确使用方法是「公钥加密私钥解密实现加解密」、「私钥加密公钥解密实现数字签名和数字验签」
非对称加解密的目的
- 一是为了保证消息的保密性,
- 二是为了保证消息来源身份三方确认(数字签名的作用)
密钥协商
一种乍一听起来比较神奇的算法,就是A和B可以在交换部分公开数据的情况下,分别在自己这里算出一个相同的数字。
举个一个很简单的例子
A和B先沟通下都选择好一个相同的数字100(可以公开),然后A自己再选定一个数字比如3(藏到裤裆里),
B也自己心里默默选好一个数字比如9(藏到裤裆里),
A将3乘以100得到300(可以公开),B将9乘以100得到900(可以公开),
然后AB之间互相交换300和900,截止到目前为止A拥有100,3,900三个数字,
而B拥有100,9,300三个数字
看好了!A将3乘以900得到2700,B将9乘以300得到2700,2700可以作为一个密钥进行加解密通信了,
而且整个过程中2700没有在网络上进行传播。
单向散列
这个应该好理解,其实就是哈希,常见犹如MD5或者SHA1、SHA2、SHA3等。单向散列是为了保证消息的完整性,粗暴说就是保证消息没有被篡改。
数字签名
非对称加解密中的RSA就可以实现,一般是为了保证消息来源身份三方确认。
就是说这个数字签名就是用来确认发送方身份的。
这种技术非常厉害,TA对如下问题作出保证
B用私钥进行加密生成数字签名,A用公钥(B的)对数字签名逆向解密,如果成功就一定表示该数据来源于B;
B要发送 “你好,吧啦巴巴 ....” 给 A 内容下面用msg代指
B先用hash函数作用要传输的内容msg,生成一个摘要(digest)
然后B用自己的私钥 作用在摘要(digest)上,生成数字签名signature
B把signature附在信件下面发给A 即发送的内容大致为msg+signature
A收取B发送的内容 msg+signature
取出signature,用B的公钥解密signature,得到digest,解密成功说明确实是B发来的
A取出msg,用同样的hash函数作用在msg得到digest1,如果digest1==disgest 说明信息没被修改过
--------------------------------------------------------------------------------------
C用了A的电脑,把B已经有的A的公钥换成了自己(C的)公钥
然后C就可以冒充B给A写信了
A发现不对,这是证书机构CA就会介入了
如果有第三个人C利用自己私钥生成数字签名,然后C劫持了B和A中间的网络,C冒充B将自己的数字签名发送给A,那么A利用B的公钥对数字签名进行解密时候,会报错!
数字证书
CA们颁发给申请者的,粗暴理解数字证书目的就是「向所有人保证来自于A的公钥真的是来自A的公钥」。数字证书中包含内容有:公钥内容,公钥内容的单向散列值,计算单向散列所用的方法,对钥内容的单向散列值的数字签名,数字证书的颁发日期以及过期时间等等众多内容...其实就是你访问HTTPS网站浏览器里那个玩意
证书.png
CA机构
颁发数字证书的机构
非对称加密
非对称加解密大概就是服务器有一对公钥和私钥,其中公钥是对任何人都开放的,而私钥必须是藏到裤裆里绝不能泄漏的。
而其使用方法也非常简单:
- 私钥加密的数据,公钥可以解密
- 公钥加密的数据,私钥可以解密
- 公钥和私钥是成双成对的,不可以乱配对乱戴帽
一般说来,正规用法都是:公钥加密私钥解密。
因为业务场景都是公钥都是像电线杆子上的小广告那样满天飞的,就是任何人都可以获取到的。所以你感受下
「私钥加密公钥解密」这个流程是不是有点儿沙雕?结合一个具体的交互过程你们感受一下:
浏览器从服务器获取到公钥
浏览器先使用公钥加密数据「一支穿云箭」,然后发送给服务器
服务器收到数据「一支穿云箭」,然后使用藏在裤裆里的私钥解密
在这个过程里,由于偷窥的人没有私钥,所以TA毛都看不到,嗯,截止到目前为止,似乎还没有遇到问题,然后我们接着交互:
服务器准备应答浏览器,他用藏在裤裆里的私钥加密好「千军万马来相见」,然后返回给了浏览器
浏览器使用公钥进行解密
这个过程就比较逗逼了,公钥是公开的,谁都能解开「千军万马来相见」,这太扯了...实际上在文章开头也提过了,非对称加解密的用法是
「公钥加密私钥解密实现加解密」、「私钥加密公钥解密实现数字签名和数字验签」
如果我们完全不在意服务器返回给客户端数据?假设说服务器返回给客户端的都是OK,加密没有任何意义。
这样就没问题了吗?然而并没有,因为还有个王炸。在众多的偷窥癖里有一类偷窥癖可以顺利成为「夹在客户端和服务器之间的中间人」(此处不要陷入到如何成为中间人的细节中),此时客户端和服务器的交流变成了这样
这种攻击就是传说中的「中间人劫持」攻击,大家可以看到此时非对称加密后的数据此时对于中间来说就是纯透明的。
在客户端面前,中间人就是服务器;在服务器面前,中间人就是客户端。客户端和服务器那些个破事儿全被扒光了。
这有点儿扯,所以也GG了
CA机构和证书
所以我们看到非对称加解密的方案里,问题根源就直接出在了第一步
:获取的公钥本身就是假的。现在问题集中在如何保证第一步沟通里的「公钥」不是伪造这个问题上来了,此时一个恰饭的机构就应运而生了:CA,他们会给你的公钥颁发一个证书,用证书告诉世界上所有人这公钥没问题,俗称证书机构。
这个机构啥意思呢,就是说:我们是全球人类都承认的客观、独立、第三方的机构,管理证书没有人比我们更专业、没有人比我们更懂证书管理、我们比任何人都更加懂保证证书真假。
所以,之前的客户端们、中间人们、服务器们三个主角中,又多来了一位:CA们。现在变成了四方大战、满身大汉!场面一度十分混乱,变成如下这样了,我整理好你们感受下:
- 客户端们
- 中间人们:假公钥假私钥
- 服务器们:真公钥真私钥
- CA们:CA公钥和CA私钥
这里流程就变成这样了
-
服务器A生成一对自己的公钥私钥,然后将公钥和自己的基本信息发送给CA们。这里的基本信息就是我叫啥、住哪儿、电话号码、域名信息等。
-
然后这里有一步至关重要的流程,那就是CA们是如何证实公钥就是来自于服务器A的呢?这里一般涉及到的认证方式有很多,
比如我们用letsencrypt时候有一种认证方式就是通过DNS来证明,甚至有些通过电话认证,更甚至通过当面+身份ID认证,这里有一个专门的CPS认证业务准则,你们有兴趣可以了解下。总之不必限于细节,我们无条件信任这个流程是100%没问题的即可。这个步骤就杜绝了CA们收到的不是中间人们的公钥,确保一定收到的是服务器们的公钥! -
CA们自己也生成了一对CA公钥和CA私钥,CA们第一步对你的公钥先进行一次单向散列(其实就是哈希)
第二步再利用自己的CA私钥对第一步里生成的单向散列值进行数字签名(这个过程请记住顺序,但是此处不必陷于单向散列和数字签名细节)形成数字证书,给服务器A(PS:这个流程CA们会收费恰饭)。
数字证书中包含的内容有:服务器A的公钥明文,服务器A的公钥明文进行单向散列后的值,单向散列的具体算法,单项散列值的数字签名(此处再保留一个问题:如果服务器A得到的数字证书是伪造的呢?) -
客户端A所在操作系统中会内置世界上所有CA们的公钥,是的这个不用你操心,反正你操作系统生产商替你包办了这个流程,此处不必陷于细节。这一步确保客户端们得到CA公钥们不是中间人伪造的公钥!
-
客户端A向服务器A发起请求,服务器A将CA们颁发给TA的数字证书发送给客户端A,此时我们已经知道客户端A已经拥有了:CA们的公钥,CA们颁发给服务器A的数字证书。这一步就算是中间人们发送的假数字证书也无所谓,先往下看第6步。
-
此处开始高能,请慢慢看流程:
首先客户端A再从数字证书中获取到单向散列的具体算法和服务器A的公钥和数字签名,
其次客户端A再利用CA们的公钥对数字签名进行「逆向」解密,此处如果解密失败表示有问题。
如果没有问题解密成功,将会得到服务器A的公钥的散列值,而散列算法也是已知的,所以客户端A会利用相同算法对服务器A的公钥进行单向散列,然后和数字证书中的服务器A的公钥的单向散列值进行对比,如果不一样,就说明这个公钥不是服务器A的公钥表示有问题。如果客户端计算出来的散列值和数字证书里的散列值一样,就说明完全没问题了。
当然还会包括有效期的验证等等,你们应该都见过HTTPS证书过期后是啥样的吧?
我们再回到第3个步骤里保留的那个问题:如果服务器A得到的数字证书是伪造的呢?这个问题实际上已经不存在了,因为第6步里客户端A利用CA公钥对数字签名进行逆向解密的时候,就是验证数字证书真伪的过程。
再经历了上述六个流程后,终于解决了开头的问题:HTTPS向客户端保证了公钥就是来自于服务器的公钥,而不是偷窥者们仿造的公钥,此处就是HTTPS解决中间人劫持的关键。
好了,现在既然已经可以保证公钥没问题,那么就是说客户端和服务器已经可以进行通信了,但是我们依然还有一个问题尚未解决:那就是客户端利用服务器公钥加密数据发送给服务器,这个方向上是没问题的;但是服务器返回给客户端的方向上加密是有问题的,因为服务器私钥加密,但是公钥任何一个人都有!怎么办?
所以在这里,HTTPS又用到了「密钥协商」和「对称加解密」技术(此处不必陷于「密钥协商」细节),流程上讲大概就是先通过「密钥协商」技术协商出一个对称加解密的密钥,然后客户端和服务器再利用这个密钥使用「对称加解密」技术对数据进行加解密工作。
HTTPS解决了三个问题
- 消息的保密性:消息本身是加密的
- 消息的完整性:消息本身没有被中间人修改过
- 消息的发送方确认性:消息一定是从来往于服务器和客户端之间,不存在任何第三方中间人中转