美文网首页iOS精英班知识点理论
看完还不懂HTTPS我直播吃翔

看完还不懂HTTPS我直播吃翔

作者: winwill2012 | 来源:发表于2017-03-24 15:19 被阅读13239次

    本文首发于我的个人技术博客看完还不懂HTTPS我直播吃翔

    存在即合理

    http是非常常见的应用层协议,是超文本传输协议的简称,其传输的内容都是明文的。在这个混乱的世界,明文传输信息想想就可怕,网络“小混混”的手段远比我们这些凡人高明得多,他们有一万种方式劫持,篡改我们的数据。对于一个网站或者服务,如果你给你的用户两个选择:

    1. 通讯数据明文传输,速度快;
    2. 通讯数据加密传输,但是速度可能会稍微慢一点.

    我想,只要脑袋没有长歪的用户都宁愿牺牲一点速度去换取数据传输的安全。

    这样,https的存在就具备了合理性,https中的s表示SSL或者TLS,就是在原http的基础上加上一层用于数据加密、解密、身份认证的安全层。

    一层层揭开HTTPS神秘面纱

    本文试图通过层层渐进方式来通俗的阐述https的原理,若有错误,欢迎大家指正。

    虽然要层层渐进,但是我们不妨先奉上刚画好的还热乎着的https通信完整流程图:


    从上图可以看到,右边有一堆钥匙,一看到钥匙我们就能想到这个过程免不了加密。另外,那些钥匙长得还不一样,有些只有一把,有些是一对,嗯,是的,你看得真仔细。

    好的,扯远了,现在开始层层渐进。

    第一层(安全传输数据)

    假如我们要实现一个功能:一个用户A给一个用户B发消息,但是要保证这个消息的内容只能被A和B知道,其他的无论是墨渊上神还是太上老君都没办法破解或者篡改消息的内容。

    如上图,需求就是这么简单,A给B发一条消息,因为比较私密,不想被其他人看到。

    由于消息不想被其他人看到,所以我们自然而然就会想到为消息加密,并且只有A和B才有解密的密钥。这里需要考虑几点:

    1. 使用什么加密方式?
    2. 密钥怎么告知对方?

    对于第一个问题,加密算法分为两类:对称加密和非对称加密,这里我们选择对称机密,原因有如下几个:

    1. 对称加密速度快,加密时CPU资源消耗少;
    2. 非对称加密对待加密的数据的长度有比较严格的要求,不能太长,但是实际中消息可能会很长(比如你给你女朋友发情书),因此非对称加密就满足不了;

    对于第二个问题,这是导致整个https通信过程很复杂的根本原因。
    如果A或B直接把他们之间用于解密的密钥通过互联网传输给对方,那一旦密钥被第三者劫持,第三者就能正确解密A,B之间的通信数据。

    第二层(安全传输密钥)

    通过第一层的描述,第二层需要解决的问题是:安全地传输A,B之间用于解密数据的密钥。

    因为如果传输过程中这把密钥被第三者拿到了,就能解密传通信数据,所以,这把密钥必须得加密,就算第三者劫持到这把加密过的密钥,他也不能解密,得到真正的密钥。

    这里有一个问题,那要用什么方式加密这把密钥呢?如果使用对称加密,那这个对称加密的密钥又怎么安全地告诉对方呢?完了,陷入死循环了.... 所以,一定不能用对称加密

    那就是用非对称加密咯,那如何应用非对称加密来加密那把密钥呢?

    考虑如下方式:


    1. 客户端: 我要发起HTTPS请求,麻烦给我一个非对称加密的公钥;
    2. 服务器: (生成一对非对称加密的密钥对,然后把公钥发给客户端),接着,这是公钥;
    3. 客户端:(收到公钥,生成一个随机数,作为上图中那一把密钥,用刚才收到的公钥加密这个密钥,然后发给服务器)这是我刚生成的加密过的密钥;
    4. 服务器:(收到加密后的密钥,用本地的第一步自己生成的非对称加密的私钥解密,得到真正的密钥);
    5. 现在,客户端和服务器都知道了这把密钥,就能愉快地用这个密钥对称加密数据...

    分析一下上面步骤的可行性:

    • 上述步骤中最终用于加密数据的密钥是客户端生成并且用公钥加密之后传给服务器的,因为私钥只有服务器才有,所以也就只有服务器才能解开客户端上报的密钥;
    • 要保证传输的密钥只能被服务器解密,就得保证用于加密密钥的公钥一定是服务器下发的,绝对不可能被第三方篡改过;

    因为还可能存在一种"中间人攻击"的情况,如下图:


    感谢XngPro的指正,上图第7步,应该是『坏人用B私钥解密得到K,然后使用A公钥加密发给服务器』

    这种情况下,客户端和服务器之间通信的数据就完全被坏人破解了。

    第三层(安全传输公钥)

    从上一层可以知道,要保证数据的安全,就必须得保证服务器给客户端下发的公钥是真正的公钥,而不是中间人伪造的公钥。那怎么保证呢?

    那就得引入数字证书了,数字证书是服务器主动去权威机构申请的,证书中包含了上一个图中的加密过的A公钥和权威机构的信息,所以服务器只需要给客户端下发数字证书即可。现在流程图如下:



    那数字证书中的A公钥是如何加密的呢?

    答案是非对称加密,只不过这里是使用只有权威机构自己才有的私钥加密。

    等一下,既然A公钥被权威机构的私钥加密了,那客户端收到证书之后怎么解密证书中的A公钥呢?需要有权威机构的公钥才能解密啊!那这个权威机构的公钥又是怎么安全地传输给客户端的呢?感觉进入了鸡生蛋,蛋生鸡的悖论了~~

    别慌,答案是权威机构的公钥不需要传输,因为权威机构会和主流的浏览器或操作系统合作,将他们的公钥内置在浏览器或操作系统环境中。客户端收到证书之后,只需要从证书中找到权威机构的信息,并从本地环境中找到权威机构的公钥,就能正确解密A公钥。

    这样就绝对安全了吗?既然权威技能能给服务器签发数字证书,那为什么就不可能给中间人签发数字证书呢?毕竟赚钱的生意权威机构也不会拒绝的呀。

    试想一下:

    服务器给客户端下发数字证书时证书被中间人劫持了,中间人将服务器的证书替换成自己的证书下发给客户端,客户端收到之后能够通过权威机构的公钥解密证书内容(因为中间人的证书也是权威机构私钥加密的),从而获取公钥,但是,这里的公钥并不是服务器原本的A公钥,而是中间人自己证书中的B公钥。从第二层可知,如果不能保证客户端收到的公钥是服务器下发的,那整个通信数据的安全就没法保证。简单总结就是证书被调包~

    所以,还得保证客户端收到的证书就是服务器下发的证书,没有被中间人篡改过。

    第四层(安全传输证书)

    这一层,我们的任务是:保证客户端收到的证书是服务器下发的证书,没有被中间人篡改过。

    所以,这里就有两个需求:

    • 证明证书内容没有被第三方篡改过;
    • 证明证书是服务器下发的;

    其实这些问题,数字证书本身已经提供方案了,数字证书中除了包含加密之后的服务器公钥,权威机构的信息之外,还包含了证书内容的签名(先通过Hash函数计算得到证书数字摘要,然后用权威机构私钥加密数字摘要得到数字签名),签名计算方法以及证书对应的域名。这样一来,客户端收到证书之后:

    • 使用权威机构的公钥解密数字证书,得到证书内容(服务器的公钥)以及证书的数字签名,然后根据证书上描述的计算证书签名的方法计算一下当前证书的签名,与收到的签名作对比,如果一样,表示证书一定是服务器下发的,没有被中间人篡改过。因为中间人虽然有权威机构的公钥,能够解析证书内容并篡改,但是篡改完成之后中间人需要将证书重新加密,但是中间人没有权威机构的私钥,无法加密,强行加密只会导致客户端无法解密,如果中间人强行乱修改证书,就会导致证书内容和证书签名不匹配。所以证书签名就能判断证书是否被篡改
    • 再考虑证书被掉包的情况:中间人同样可以向权威机构申请一份证书,然后在服务器给客户端下发证书的时候劫持原证书,将自己的假证书下发给客户端,客户端收到之后依然能够使用权威机构的公钥解密证书,并且证书签名也没问题。但是这个时候客户端还需要检查证书中的域名和当前访问的域名是否一致。如果不一致,会发出警告!

    从上面的分析可以看到,数字证书中的信息确实能让客户端辨别证书的真伪。

    怎么样?经过这么几句通俗的话,是不是对HTTPS的通信机制有了比较清晰的认识了。当然了,有一些可能是我胡扯的,不一定对,大家多多指正!

    相关文章

      网友评论

      • mandypig:其实作者前面都写得非常好,但是在如何保证客户端收到的证书是CA颁发而没有被中间人篡改这部分确实没有讲清楚,我网上查了很多资料也没一个清楚的解释,实在是揪心
      • 傅青云:请问,客户端首先发起https请求服务器生成公钥,那这怎么保证请求是合法的呢???
      • QCTECHIE:我还是不懂!请告诉我你的直播间,然后开始你的表演🤔
      • 望川秋裤一郎:写的不错,请问在哪里直播
      • 0445981d6022:可以可以,吃翔我就不看了。
      • 77968bbd24e5:写的很棒,我也差不多看懂了,然后,还是想问问在哪儿播吃翔
      • e4077121186f:播了吗?
      • mico米高:@con_3ac3 改了之后,签名证书不匹配。签名证书需要权威机构私钥,没办法造假:stuck_out_tongue_winking_eye:
      • 萌萌的白天:我已经看完了 还是不懂你在哪里吃
      • 月肃生:有点晕,大致明白了一点,可能要多看几遍才行
      • xc浩:我是进来看评论的
      • 我是Python小白:大概差不多也许是第五次看这篇文章,初闻不知曲中意,再听已是曲中人。
      • 48b1856997bf:那个看不懂中文,所以你在哪直播?
      • 华仔Harry:挺通俗的,昨天还做过类似第二步的ssh key exchange。证书申请是其他组的工作
      • 最怕认真:为了让你吃翔,我特意把脑子放在家里才来看文章
      • mandypig:虽然没完全看懂,但还是看懂了一部分,需要结合其他文章慢慢消化才行
      • 色粉红豹:请问,在哪直播:joy:
        winwill2012:虎牙直播
      • 秋雨无痕:确实是看不懂:stuck_out_tongue_winking_eye:
      • c9ccbad2016d:申请SSL证书请到环洋诚信
      • LoveY34:你好!有一个问题:证书签名需要使用权威机构的私钥加密证书摘要,客户端怎么用同样的办法生成证书签名呢?客户端没有权威机构的私钥啊?
        容我荣少长流芳:@LoveY34 你可以去购买证书
      • eebd372d985f:麻烦问一下, 你画图是用的什么软件
      • 老骥成长:有个小小的疑问:下面这段话,客户端如何加密生成数字签名啊,客户端并没有权威机构的私钥

        使用权威机构的公钥解密数字证书,得到证书内容(服务器的公钥)以及证书的数字签名,然后根据证书上描述的计算证书签名的方法计算一下当前证书的签名,与收到的签名作对比,如果一样,表示证书一定是服务器下发的
      • 风雨落山岚:看不懂,想看吃翔:smirk:
      • 3eb9cb2bfb2e:写的真不错,循序渐进的剖析,道理也是浅显易懂!赞!
      • 我本善良:言简意赅,但是在ssl证书调包的解释中:CA有很多,一个域名能同时申请多个CA吗?如果能申请多个CA的话,那调包还是可以发生。
      • 仓颉空:大家都说看不懂,我怎么能看懂,坐等直播:joy:
      • con_3ac3:中间人自己的域名也可以改啊
      • 小玉的晓:太棒了
      • Manuel谦虚谨慎:看不懂啊,大胸弟
      • 玩阿轲睡妲己:没看懂,等直播
      • KengG:大兄弟
      • 4fec4ada4955:那个(挠头)……我可能没懂,
      • FoolishFlyFox:写得很棒:+1:
      • zwStar:写得非常详细 超赞:+1:🏻
      • 破弓:您好,谢谢您对HTTPS的透彻的分享.同时我也看了另一篇文章==>http://www.jianshu.com/p/650ad90bf563,除了证书之外,这篇文章中还反复的提到发送信息前会生成校验值,然后信息+校验值一起发给对方,你看有这么回事吗?
      • 天地不仁以万物为刍狗:握草 这个禽兽写的太棒了,赏你一个萌萌哒:smile:
      • 11a3cf40db0d:大兄弟搁哪里直播啊
      • 择一城终老_蜗牛:哥们:heart_eyes:我直接先看评论了,发现好多人没看懂,我觉得我也看不懂呀!求直播链接:relieved:
      • 067253cd06b9:都没看懂啊
        winwill2012:@铭记阳光 你的良心会痛吗
      • 春田花花幼儿园:作者, 你好, 写的很好,很容易看懂!!! 但是有个地方有个疑问. 就是最后一小节. "然后根据证书上描述的计算证书签名的方法计算一下当前证书的签名", 上边描述的签名生成的方法是"(先通过Hash函数计算得到证书数字摘要,然后用权威机构私钥加密数字摘要得到数字签名)", 但是客户端没有 [私有钥匙 + HSAH 计算得到的数字摘要],怎么进行生成签名,又和证书的签名作比较呢?
      • 春田花花幼儿园:我都看完了, 你才说"当然了,有一些可能是我胡扯的",哈哈,写的很清晰
        winwill2012:@春田花花幼儿园 你就当我扯淡就行了哈哈
      • 5b651a0547e8:所以最好不要信任国内的CA,什么事都能看出来,前段时间主流浏览器刚把某国内的证书吊销了。
      • 我是Python小白:感谢作者的分享,几幅插图很经典,一目了然。:smile:
        winwill2012: @iOS_Reverse 有用就好
      • 0040df147a21:这里我们选择对称 机 密
      • Mrwyr:Talk is cheap, Show me the code
      • e2f51e8cb723::+1: 看懂了
      • ZZFA:坐等公布直播房间号!
      • 扑克牌_6957:使用权威机构的公钥解密数字证书,得到证书内容(服务器的公钥)以及证书的数字签名,然后根据证书上描述的计算证书签名的方法计算一下当前证书的签名,与收到的签名作对比,如果一样,表示证书一定是服务器下发的,没有被中间人篡改过。
        能通过证书上描述的计算证书签名的方法计算得出签名,就不能通过这个方法伪造?
      • 3a116c3f088d:写得不错,虽然本来已经懂了,但是为了看直播还是要假装一下看不懂
      • 燃_ef99:完完全全看不懂啊 懵逼了
      • 808876efc072:这...这肯定要装作没看懂啊!忍不住想笑,我可以提供翔喔?
      • Superbsco:看完了。大概懂了。
      • 忙到忘变了心:直接拉到评论区的+1,怎么没有直播地址啊?
      • 978e86a8a255:我表示看懂了 !!!哈哈哈哈!!!
      • Andy_Ron:为何要对自己这么狠呢!?

        喝尿就行了!:stuck_out_tongue_closed_eyes::stuck_out_tongue_closed_eyes:
      • 萤火之森ss:哇,我一秒就全看完了,立即拉下来看评论
      • 8f722fed8b2a:放心,我们都会装作看不懂的样子,就为了下一场直播
      • 换个啥:大胸帝,我还是没看懂咋办?
      • 47aff8bcc38c:你博客地址挂了,顺便等着看吃翔
      • 85a6df6f36aa:哈 假装自己没看懂 😜😜 另外告诉我一下房间号 😌😌
      • 2051bcb3e4e3:小白表示从未看过直播吃翔
      • iGOGOo:文章只是说了 客户端发数据到服务端安全 那服务端到客户端呢 一般好像都是单向验证
      • e49f931239e1:写的很好, 不过还可以更加生动点, 所以..我没看懂,估计看完直播我就懂了 :smile:
        winwill2012: @广州六叔 不厚道啊兄弟
      • 起个文艺的名字:请告诉我直播房间
      • Dwyane_Coding:😬写得不错,加油
      • 自负的大撸sir:大神大神!有个问题:既然客户端已经有了需要被加密的密钥了 为什么还要生成一个随机数 然后用服务器传回来的公钥给随机数机密呐????
        75d72d547d6a:@自负的大撸sir 你在想想
        自负的大撸sir:@winwill2012 我重新捋了一下 想明白了!但现在又有2问题:

        1. “如果中间人强行乱修改证书,就会导致证书内容和证书签名不匹配”
        - 强行修改证书,是修改证书的公钥?
        - 强行修改证书后,通过原始证书的签名算法计算出数字签名,证书内容和证书签名怎么不匹配了?

        2. “但是这个时候客户端还需要检查证书中的域名和当前访问的域名是否一致”
        - 证书被掉包后,证书中的域名就改变了?
        - 如果证书被掉包后证书域名被改变了,那么客户端拿到被掉包的证书以后,并不会知道域名被改变了啊,客户端怎么对域名进行比较呢?
        winwill2012:@自负的大撸sir 你想想哈,访问一个网站的人那么多,了应该每个客户端都用同一个密钥啊,要不然跟没加密有啥区别
      • 黑色小核:中间人为什么一定要篡改证书或者更换密匙B呢?
        我把密匙A复制一份,再把密匙A再转发给用户不行吗?这样我照样可以获取随机数K,而且还没有篡改任何东西。
        winwill2012:@smile_罗斯 你说的密钥A是公钥还是私钥?
        黑色小核: @winwill2012 不知道啊,我就是想不明白这个
        winwill2012:@smile_罗斯 真的可以吗?
      • LLVKS:弱鸡表示不懂
      • 伟大的顾大大:讲得很好,不过黑客植入伪造根证书的方法还是可以进行流量解密
      • 想名字太难了:假装看懂了
      • i顺颂时宜:公钥是加密,私钥是解密吧。博文中的第三层中的 数字证书中的A公钥被权威机构的私钥加密了,怎么得到解密的公钥:joy:说反了了吧
        winwill2012:@赵先生Try 这个无所谓,公钥加密私钥解密,私钥加密公钥解密
        i顺颂时宜:文中说到公钥解密,貌似解密是私钥,加密才是公钥吧?
        winwill2012:权威机构会和浏览器和操作系统合作,将他们的公钥内置在系统或者浏览器中,所以客户端拿到证书之后只需要从本地找到权威机构的公钥就能解密。
      • uuid1234:进来看吃翔:grin:
      • Shaneee:你以为我这样就懂了吗?你太天真了
      • 24c2adb3c9b7:第四层安全传输证书看不太懂
      • f733fa4047ee::yum: 也许我真的看懂了,但是看了下评论,所以我真的没有看懂啊~~记得发链接哦
        f733fa4047ee:@winwill2012 :stuck_out_tongue: 表生气哈,图文搭配,真心写的很清晰
        winwill2012:过分了老铁
      • 喝可乐的熊:留下直播地址😂
      • 5e0fd043a6c4:没看懂 直播几点开 我等着
      • LittleSakana:写的不错,完全懂要看两遍
      • 黑黑的小土豆:求直播地址
      • Farsight:我一定要装作看不懂😎
      • 同Young不同样:快,直播的时候我给你送鱼丸,或者竹子也行😂😂😂
      • 709b16930696:直播地址在哪里,我完全不懂啊
      • dkStart:感觉第二层( 安全传输密钥),那个图的第七步写的有问题,坏人用b私钥解密获得k后,应该使用a公钥去加密k给服务端,而不是b公钥
        winwill2012:是的,已经纠正了,多谢!
      • 9d426ee34834:平台直播号多少?:smile:
      • Mooner_guo:所以,鉴别是否受到中间人攻击(篡改、掉包证书)的方法:
        (1)CA的给的证书签名可以保证证书不会被篡改
        (2)比对请求域名和访问域名是否一致,不一致则被证明证书被掉包了。
        双击666
      • 梁同桌:老铁66666666666
        你少解释一个东西,
        1.私钥加密的只有公钥解密
        2.公钥加密的只有私钥解密

        还有一个疑问,既然大家都可以用私钥和公钥加密解密,还要K干嘛?
        梁同桌:@Kobe24_33 你是对的,事实就是如此非对称效率低
        1024a21fd2cb:@winwill2012 我觉得还有其他的原因,因为非对称加密算法的加密和解密过程非常耗时,是对称加密的1000倍,所以有了秘钥K~
        winwill2012:是少解释了,多谢你的补充。
        因为非对称加密对加密的数据的长度有限制(不能太长),所以如果直接用非对称加密加密数据会满足不了加密长数据的需求。
      • 3d82f357f8f9:讲的可以,加油。
      • e3f43e419756:对不起了大兄弟,给你兑一坨?
      • 谢聃:标题十分吸引人,这还是刚开始写简书的人?看评论感觉咋这么多人等你出丑呢?也许大家都是开玩笑吧
      • 飞翼5280:我直接看评论了……
      • ce974b18516c:完全看不懂。。。。。。
      • 漂之100:那中间人可不可以伪造域名呐?比如中间人在路由器上动手脚,把客户端连接的域名伪造?
      • 码无止境:直播地址在哪?😂
      • ccea8f61025f:为了支持你直播,我都没看就知道我看不懂了。直播的时候记得发下平台和房间号:joy:
      • 此处轩辕:证书签名是用权威机构私钥加密后传给客户端的,就算有计算方法,客户端也没办法算出来证书签名吧,怎么做对比?而且中间人也可以根据计算方法弄一个一样的签名啊
        此处轩辕: @winwill2012 权威机构的私钥加密的是签名还是证书?如果是签名的话,客户端怎么按照计算方法计算签名,毕竟签名是加密的,而客户端也不能解密签名啊
        winwill2012:@此处轩辕 中间人确实可以自己计算签名,但是计算之后他没有权威机构的私钥,没办法加密
      • 微笑在天上飞iii:计算机网络课学过,当时被绕蒙了,经过这个看懂了,也记得很清楚,但是,要装作没看懂啊
        winwill2012:过分啦
      • shushuzhen:只要你直播,我肯定看

      本文标题:看完还不懂HTTPS我直播吃翔

      本文链接:https://www.haomeiwen.com/subject/vnrfottx.html