• PKI体系下的 SSL TLS HTTPS 详解


    背景:
      SSL(Secure Socket Layer 安全套接层)是一个加密函数库,它可以将应用层上所有明文传输的数据,通过调用SSL库,即可摇身一变成为安全通信连接,SSL最初是由网景公司(Netscape)研发,目前现有版本为SSLv1,SSLv2,SSLv3,但v1,v2已经淘汰,目前基本使用v3,后来IETF(The Internet Engineering Task Force - 互联网工程任务组)将其标准化后,命名为TLS(Transport Layer Security 安全传输层协议),目前已经发展出三个版本:TLSv1.0, TLSv1.1,TLSv1.2, 并且TLS也已经写入RFC(RFCRequest For Comments 请求注释)中, 文档编号: RFC2246
    注: RFC是Internet协议字典,它里包含了所有互联网技术的规范!RFC官方网站: www.rfc-editor.org
      目前TLSv1 相当于 SSLv3,通常我们将可不对它们做过细的区分,但是在使用某些软件时,它可能会只支持SSL或TLS或都支持,这就需要自行选择了。

    SSL和TLS的实现功能基本一致,但也有差别,具体若要编程使用,就需要具体了解,这篇文章中提到了一些区别,可做参考:
      https://blog.csdn.net/enweitech/article/details/81781405

    这篇博文介绍了自建CA的步骤,可做参考学习,当然也可自己查询其他. 

      http://www.mamicode.com/info-detail-1846390.html

      下图就是TLS/SSL在TCP/IP四层模型中的位置:

      

      HTTPS:
      在说明HTTPS前,我先简单的说明一下HTTP的发展史,以便在这个基础上来理解HTTPS.
      HTTP的简单历史表:

        

     为了便于理解http的发展史,我仅做基本说明:
      http/0.9: 这是最初的http,作者是为了让招聘者可以看到自己的简历.而创造.
          哪知道http横空出世,带来了互联网的春天.当然这也有赖于www的发明者.
          具体我印象模糊了. http诞生的原因很简单,所以它也就没有考虑那么周全,但当网络发展
          方兴未艾之时,遇到http协议,真实入鱼得水,人们发现http可用用页面方式展示内容,于是关于
          http的应用也开始兴起,网景公司就抓住这个时机,开发了世界上第一个浏览器,也因此赚了很
          多钱,但正当http应用红火时,人们发现http可以展示内容,但它都是明文传输的,只要有人拦截
          了数据包,就可以知道我和别人的所有通信内容,这对未来发展网络购物,用户隐私等方面会带来
          很大隐患,于是网景公司就在94年开发了SSL加密库,让http应用调用这个加密库,来将隐私信息
          加密传送,这样就可以解决隐患. 接着IETF发现SSL这东西不错,不过这东西是商业化的,不利于标准化,
          于是IETF就主导开发了TSL,后来在2000年终于诞生了https标准,这是后话,接着说http.


      http/1.0: 由于0.9版,只能支持文本展示,这太单调了,于是在这样旺盛的需求下,1.0诞生了,它引入了更多新的功能
          终于让页面上可以同时显示图片,文本,音乐等等信息,这就MIME,啊~感觉好兴奋.
          但是,MIME的引入带来了http需求的更大增长,网页上的内容越来越丰富,但是打开网页的等待时间却越来
          越长,人们看着白白的网页感叹~好卡!怎么办!

        http/1.1:在99年http/1.1.诞生了,它引入了持久连接功能,及其它特性,持久连接?简单说就是:1.0时代,你
          为了完成从邻居家借一套笔墨纸橡皮画画,你不得不这样做:
          你-----[敲门: 在吗?]------------------邻居
          邻居---[在]-------------------------------你
          你------[开下门]------------------------邻居
          你------[我想借一张纸]-----------------邻居
          邻居---[可以,给, 咔嚓,门关了]----------你

          你发现你只借到了纸,但没有铅笔呀.于是
          你-----[敲门: 在吗?]------------------邻居
          邻居---[在]--------------------------------你
          你------[开下门]------------------------邻居
          你------[我想借一支铅笔]-------------邻居
          邻居---[可以,给, 咔嚓,门关了]----------你

          你发现你只借到了纸和铅笔,但没有小刀,削铅笔呀.于是
          你又重复了上面的动作.....
          有了小刀,你发现你没有橡皮,于是你又重复了上面的动作.....
          最终你终于可以画画了....
          1.1时代,你终于可以一口气说完自己的所有需要了.这就是持久连接的好处.当然1.1的改进不仅如此,
          它还引入了缓存机制,错误通知管理,及带宽优化,其中range头,可允许仅请求一个页面中的一部分
          内容来展示,若我不喜欢,我就不在往下看了,也不用再传下面的内容了.所以带宽优化了不少.
          于是我们高兴的进入了http/1.1时代,这看上去都很不错,但从99年开始互联网经济发展正如火如荼
          网络购物,银行转账,你给你漂亮的女朋友发求婚邮件等等需求,都需要网络安全得到保障.于是
      HTTPS: 被推到历史前沿, 正如前面介绍,http+ssl=https,但这是商业的呀, IETF的工作让TLS诞生了,因此HTTPS
          标准化就有了前提。看似https的出现让我们的网络安全了,http/1.1又让我们进入了多媒体网页时代,这
          一切似乎完美解决了问题?其实不然,随着网络应用的增加,https在那个硬件基础薄弱的年代,是个花架子,
          只有涉及到非常私密的数据传输时,才会使用它,否则绝不使用,因为它太消耗资源了,另一方面,随着使用量
          的增加.http/1.1也出现了诸多问题,首先是网页以打开,服务器端就死命的发数据,虽然可以只发一部分,但
          图片,视频,文本等也依然不少,信息一个一个排着队不停发,但服务器端网络带宽也有限呀,而也贵呀,
          另外移动应用逐渐兴起,移动流量那叫一个贵呀,你死命发数据给我,我这边带宽也小呀,因此客户端
          又发出好卡!的感叹. 

          同时http/1.1引入的一些新特性,如http头可增加字段,如:cookie等信息,来识别这个用户
          之前来过,这本来很好,因为集群环境中有多台WebServer,用户第一次打开网页,他选购了一些物品放到
          购物车中,但他感觉有点卡,他一刷新,他竟然在服务器端被调度到WebServer2上了,但WebServer2上
          没有他刚才选购的东西,咋办?告诉用户 你的购物车是空的?所以cookie很重要,WebServer通过Cookie
          知道这个用户是谁,与此Cookie对应的内容就是他访问我时,产生的临时数据,即购物车中的物品.
          把上面这些信息关联起来,就使得http/1.1的数据包很大,而且重复数据也很多,这不仅让客户端感觉累,
          让服务器端更加累; 再结合http/1.1+TSL=https,可想而知,本来只有http/1.1就累的不行,再加上加密
          解密,认证的过程,就知道https为何难以大规模使用了.
            注: 在早期有胖cookie和瘦cookie之分: 胖cookie就是所有信息都放到cookie中,瘦cookie就是
              仅在cookie中放重要标识信息; 胖cookie可让服务器端代码容易实现,架构更简单,瘦cookie相反
              需要投入更多硬件成本,代码实现难度大. 胖好瘦好?各有优劣,胖了占带宽,带宽高了,访问慢,通信
              费用也会噌噌往上涨.

      SPDY: 时间到了09年,http/1.1的问题这么大,安全需求也越来越强,时代需要变革,Google在这时就推出了SPDY来
          响应时代的号召,提出了http头部压缩,请求优先级等特性, http头压缩,就让胖瘦cookie,变得不是事了, 请求
          优先级让服务器可先将重要的数据先发给用户,次要的数据后发给用户,比如:先发文本信息,不让用户对着白白
          的网页发呆,后把图片,视频等资源传过去,慢慢全部呈现.并且它强制使用https,让数据传输更安全了.

      http/2.0:SPDY的升级版, 引入了SPDY的诸多优点,并且开放了可以使用http明文传输,混乱得到再次停息。

      以上就是我所理解的http发展大话史,仅做参考,不是完全正确,甚至有些是错误的,但为了方便理解可先简单这样理解.
      现在我们也逐渐清楚,https的意义,但是HTTPS究竟是如何实现安全的?使用TSL?TSL又是如何实现安全的?

      TSL是如何实现安全的:
        要说清楚TSL如何实现安全,我们就要从当今互联网信任基础架构 PKI 说起.
        PKI: Public Key Infrastructure: 公钥基础设施
        公钥? 公钥是从私钥中按照一定的算法提取出来的密码.这个密码很长,且不用于用户名口令的方式使用.所以给它起了个名字叫公钥.
        这就是一个公钥示例:

          

        下面是生成该公钥的私钥:

          

        他俩有什么用?
        要说清楚,还有从原点说起:

         

           主人公介绍:
          Alias:女主角,Bob:男友,Eve:Bob的情敌

      说明前的铺垫:
        机密性: 明文传输(FTP, HTTP, SNMP, TELNET)
            要实现让这些明文传输数据的应用安全,最初只能使用对称加密:通信双方使用相同密码。
            补充:
              对称加密算法:
              1. DES: Data Encrption Standard数据加密标准,它采用56位密钥进行数据加密
              2. 3DES:三重数据加密表
              3. AES:高级加密标准,它有多种变种,如: AES192, AES256, AES512等,---》这里的数字是,加密的位数。
              4. Blowfish
        完整性:
          单向加密算法 : 用于提取数据特征码,又称为数据摘要算法,比较常见的有: md5, sha256等...
            它的特点:
              输入一样:输出必然相同。
              雪崩效应:输入的微小改变,将会引起结果的巨大改变.

                

                   'ab'和'ab ': 只是多了一个空格!!
              定长输出:无论原始数据是多少,结果大小都是相同的,如上图:两个字符和三个字符,输出结果长度都一样.
              不可逆:无法根据特征码还原原来数据。
                  如: 你能从结果还原ab吗?
                  但: 事实证明,上海复旦女博士已经证明可以还原,但随着密钥位数增加,破解难度也会成几何倍增.
                  补充:
                    单向加密算法:【注意:单向加密算法是定长输出】
                      1. MD4
                      2. MD5 ----》MD4和MD5输出长度都是128位 【md5sum inittab --》生成inittab的指纹】
                      3. SHA1 ---》它的输出长度为160位
                      4. SHA192, SHA256, SHA384 -----》这里的数字指的是定长输出的长度。 【sha1sum inittab --》生成inittab的指纹】
                      5. CRC-32: 循环冗余校验码,它只是一种循环校验码的机制,它不提供数据的加密,故它不提供任何安全性。

    有了以上前提说明后,下面开始深入
     说明:
      特征码: 下文中将不断提到特征码,它是单向加密算法计算出来的一串字符串.
         下文中说的特征码,可简单理解为:
         Bob:给Alias发了一封邮件, 内容: Alias,做我女朋友吧! Bob不希望别人修改它的原话,
            就对这句话,使用sha256sum 计算出一串字符串, 只要Alias收到后,也用sha256sum
            计算一下这句话,只要特征码一样,就可以确定这句话没有被篡改过.
      好故事开始:
        A: Alias, B:Bob, E:Eve
        A :plaintext:footprint(特征码) --------------》 B
          A给B通信时,将要发的明文通过单向加密算法计算出这段明文的特征码,并附带在明文的后面,发给B。
          B收到后,只要对相同明文做单向加密得到的值一定与附带的特征码相同。若不同则说明文有问题。
        E : plaintext2:footprint2 -----------------》B
          如上,由于A和B通信时,存在中间人攻击,A发给B的数据被E截获了,并修改了明文,并且对特征码重新计算。最后发给B。
          B收到后,无论他怎么计算这段明文都与 特征码一样。
        A :plainttext:加密(footprint) ----------------》B


      为了避免这种问题,A给B发信时,对特征码加密后,发给B,这时即便E截获了数据,他也不可能知道解密特征码的密码。
    那么即便E修改了明文,重做特征码也没用。这确实安全了,但是,又出现两问题:
      1. 假如A与B通信使用一个密码,A与C通信使用一个密码,A与.....n 多人通信都要使用密码,那么密码管理将变的困难,
        若密码都用相同的,那么基本上没有安全性可言了。
      2. 在现实网络中两台从来没有通过信的主机要通信,哪这个密码又该如何进行告知???两个人都不认识,如何告知密码?

      怎么办? 为了解决这些问题,又出现了一个密钥加密算法:
      协商生成密码:密钥交换(Internet Key Exchange: IKE)协议, 它使用Diffie-Hellman算法实现,它其实是两个牛人的名字组合.
        Diffie-Hellman协议(或叫算法):
        还是A 和 B要进行安全通信。
          A:使用自定义的数字:x,并使用两个很大的素数: p 和 h, 接着将 p, h,h^x%p 的值发给 B。
          B: B收到A发来的数值后,使用数字:y, h 和 P,做如此运算: h^y%p ,并将其值发给 A。

          这个过程中四个数值 : h p (h^x%p) (h^y%p) ,通过网络明文相互发到 A 和 B上。

          A:收到后,将B发的 (h^y%p)的值在与x进行幂运算:(h^y%p)^x = h^xy%p
          B: 收到后,将A发的 (h^x%p)的值在与y进行幂运算:(h^x%p)^y = h^xy%p
        这样A和B两人就得到了属于他们两的共同的密钥了。其中,即便那四个值在网络中被人看到,他们也很难推算出x 和 y的值。
        由此,A 和 B通信在也不需为密码而烦恼了,双方只要使用一个工具,这个工具使用Diffie-hellman算法自动协商密码
        并自动对通信的明文做特征码,并加密该特征码,这样问题不就简单了。

      问题看似解决了,但新的问题又来了,因为密码是自动生成的,所以,Bob无法向先前那样通过两人共同的密码,判断对方就是Alias,
    因此Bob并不知道跟他通信的人一定是Alias,这时Eve又在他俩之间,拦截Alias发给Bob的信息,并向Bob发送虚假信息称自己就是Alias,
    这样一来,问题转了一圈又回来了,安全性又无从谈起了。接着,安全系统再次升级,出现了身份验证方法,即非对称加密算法(即:公钥加密算法)

      说明前铺垫:
        非对称加密算法:RSA, DSA,它能实现,用私钥加密的数据,只有该私钥生成的公钥可以解密, 反过来,公钥加密的数据,也只有私钥可以解密!
            因此,A用自己的私钥加密,只有A的公钥可解密,这样就能保障A发信息使用A的私钥加密,只有A的公钥可以解密,能用A的公钥解密
            数据,就一定说明该数据是A发的.

      身份验证:
        非对称加密算法:(公钥加密算法)

        现在Alias给Bob发邮件,Alias使用自己的私钥加密邮件,发给Bob,若Bob使用Alias的公钥能解密邮件,则说明对方一定是Alias,这没错,
       同样Alias的公钥是公开的Eve就也可以解密邮件,这样邮件的机密性就无从保证了;
             若Alias发信时使用Bob的公钥加密数据,那么这次就只有Bob可以解密,因为Bob才有自己的私钥,但这样一来,Eve又冒充Alias使用Bob的
         公钥加密数据后发给Bob,Bob依然可以解密,那么身份验证又无法保证了。

        发送方用自己的私钥加密数据,可实现身份验证,但不能实现数据机密性。因为:私钥只有自己有,公钥是公开的,
      因此别人是无法使用你的私钥加数据的,但可以查看你的数据。
        发送方用对方的公钥加密数据,可保证数据的机密性,但不能实现身份验证。
       【上面举例,实际上公钥加密算法很少用来加密数据:速度太慢, 因为:公钥加密算法的密钥太长了,而且公钥加密算法比对称加密算法慢3个数量级,
          一个数量级是10倍,3个就是1000倍】

      但实际上,公钥加密算法并不是用来保证数据的机密性的,它主要用来保证数据的 完整性 和 身份验证,看下面这个场景:
           Alias要向Bob发信,Alias使用单向加密算法可以先计算这份数据的特征码,接着使用自己的私钥加密这段特征码,再发给Bob,这样即便Eve在中间截取了Alias的数据,
    他即便对这段数据修改,也可以解密特征码,但他却不能还原特征码,因为Eve没有Alias的私钥,这样Eve在发给Bob,Bob就肯定可以发觉。

      你会不会想?那为何不用Bob的公钥加密数据,用Alias的私钥加密特征码?
         其实逻辑上这样是可以的,因为Bob公钥加密数据,只有Bob可以解密,Alias私钥加密特征码,Eve可以看,但他无法修改,看上去这方案可行,但实际上,
      此做法实际中不可行,正如前面说明,非对称加密不适合加密数据,因为密钥太长,加密后文件会变大,而且时间长的让人不能接受!!我印象中1G的数据用对称加密
      和非对称加密算法做加解密测试,发现加密耗时似乎差不多大概2小时左右,但解密对称加密是2~4个小时左右,但非对称加密是80~小时以上!!所以你可以自行
      测试,具体我就不说了。

      仔细看这个过程,会发现“公钥”在其中起了比较关键的作用,哪Bob要解密Alias的用私钥加密的数据,Bob如何得到Alias的公钥,假如Bob和Alias从未联系过,如何进行,
    若Bob直接给Alias发信说,把你的公钥给我一份, Alias就给Bob发一份, 哪Bob怎么知道就是Alias把自己的公钥给了自己,而不是Eve在中间冒充了Alias给Bob发了Eve的
    公钥,说这是Alias的公钥。因此,问题似乎又一次回到原点了。

      安全体系继续升级,出现下面这种结构,竟然公钥很难得到公正,那么就出现了CA,就像公安部,我们说自己是中国公民,何以为证?当然,身份证户口本就是证明,
    哪我随便拿一张纸写上身份证,能算数吗?肯定不能,所以就需要有公安部的防伪标记,并且还需大家都信任公安部,否则就无从谈起。这时,Alias就可以将
    自己的信息和公钥发给CA,有CA来做公正,并为Alias做一个证书,当然,公安部要给其他人做公正,就必须先自己给自己做公正,让自己成为合法的(自封为王);
    接着CA使用自己的私钥对Alias提交的个人信息及Alias的公钥的特征码加密,这就是“戳”;当Bob要获取Alias的公钥,Alias可以直接给Bob一个自己的证书,
    Bob使用发证机构CA的证书中CA的公钥解密“戳“, 并对Alias的信息计算特征码,做对比,若一样,则说明这就是Alias的公钥。Alias与Bob是一样的,
    使用同样的方法就可以得到Bob的公钥了。

    密钥对:
      公钥:P
      私钥:s

        

     假如现在Alias和Bob通信,他们之间都已经有了对方的公钥,Alias将数据发给Bob前,先协商密码,Alias使用自己的私钥加密通信内容的特征码,并使用双方协商的密码
    加密数据和私钥加密后的特征码这样就保证了通信的安全,Bob收到密文后,使用协商的密码,解密 密文,使用Alias的公钥解密特征码,确认Alias的身份,使用单向加密
    算法计算数据的特征码,对比 保证数据的完整性。但这又使用协商密码了,又不方便了。但实际上,这个过程是这样的,Alias在向Bob发信时,先随机生成一个密码,
    用这个密码对数据和私钥加密的特征码加密,接着使用Bob的公钥对随机密码加密,最后,将这些数据一起发给Bob,那么,只有Bob可以解密Alias的随机密码,并使用
    随机密码解密加密的数据,接着使用Alias的公钥解密特征码,对比数据的特征码,保证数据的完整性。这样,数据传递的机密性,完整性,身份认证都得到了保障。
      过程如下:

        RK: RandomKey(随机密码)
        SKa: Alias的私钥
        PKb: Bob的公钥
        A-----[RK{ Data + SKa{Data特征码} } PKb{RandomKey}] -------------------------->B

      接着说CA:
      公安部若给全球人民颁发证书,公安部肯定要忙死!所以一般公安部是不直接给任何人颁发证书的,颁发证书的事都由具体的各级的各个派出机构来负责具体的证书颁发
    你信任公安部,那么你就必须要信任他的派出机构;CA证书颁发机构也是如此,全球有大概有13家证书颁发机构,他们就是这样做的。所以,这整个信任体系够构成了
    当今互联网安全通信的框架,而这个框架就是PKI 体系。
    【PKI: Public Key Infrastructure:公钥基础设施,PKI的核心即是证书颁发机构,证书撤销列表 和 它的彼此间的信任关系】
      CA:certificate authority
      CRL:证书撤销列表

        

       最后:
      若你的私钥丢失了,哪证书就失去意义了,哪这要怎么办? 一个公司或组织他们的重要证明信息,如:法人章,营业执照,等丢了,
    别人就可以冒充你来与人签合同,但作为丢失方,可以让当地的知名媒体通告这件事,宣布丢失的物品作废。
      那我们的私钥丢了该怎么办,这就需要联系生活,我们的银行U盾(个人证书),在使用时是不是要求我们输入密码才能使用,同样我们的私钥丢了,
    我们也可以对私钥加密啊,这样别人拿到了,也不能使用。但这样带来的问题,每次要使用私钥时都需要输入密码,是不是也很让人受不了,怎么办,
    借助软件来帮我们输入密码,哪我们的服务器被攻破了,它还有意义吗?还有, 若软件有问题哪?,说到底,
    记住: 世界上没有决对的安全。


    通过上面这一大段PKI体系说明,终于可以继续说HTTPS了:
    当Client向服务器发起HTTPS的请求后,当三次握手完成后

      

              第一步:Client向Server发起加密通信请求,接着Server回应并与Client协商使用SSLv3 或 TLSv1等来进行消息封装,
            并协商使用那种对称加密算法来进行数据加密;【注意:HTTPS并没有使用IKE( Internet密钥交换)中的DH算法】

        第二步:协商完成后,Server将自身的证书发给Client,Client收到证书后,开始验证证书是否为信任的CA证书颁发机构颁发的
            若是,则使用信任CA的公钥,验证其Server的证书信息的完整性,即验证Server就是Server所声称的自己;
            Client如何获取CA的证书?

              

        以上就是Handshake(握手过程)。

        第三步:Client使用Server端的公钥,加密随机生成的一个会话密码,并发给Server端,注意这里使用的是对称加密算法,
            来保证通信的机密性;
        第四步:Server端就可以使用Client发来的会话密码,与Client建立对称密码加密通信了。

          以上两步就完成了Change Cipher Spcial(专用密码交换)
          Alert:即通信过程中若出现异常错误的报警机制.
            摘录补充:
              报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,
                  如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、
                  拒绝访问(access_denied)等

      以上四步其实就是TLS通信的第一个子协议, TLS Handshake握手协议的全过程.
        TLS第二个子协议: TLS Record(TLS记录协议):
          它主要做四件事:
            Fragmentation : 封装
              这是TCP/IP通信最基本概念,封装可简单理解为:一个名字标识,计算机中已经预先定义了不同
              协议名对应那些处理程序来打开。
            Compression :压缩
              因为数据越大加密和解密速度越慢,因此压缩是必须的.
            Authentication : 身份认证
              因为Client可通过CA的公钥验证Server的身份,Client使用的Server的公钥加密随机密码,只有Server
              能解密,凡是能使用此次通信协商出来的随机密码解密数据的人,就只有我和你,因此也就可以验证彼此的
              身份,当第二次在某个时间我们又通信时,我们还是要从第一个子协议开始,协商过程,再次得到通信的
              随机密码,因此可保证每次通信都使用的是会话密码,即Session key,也叫Short-trem key.所以通信
              的完整性,机密性,身份验证就做到了.
            Encryption :数据加密
              这里加密是使用对称加密算法(DES,3DES,RC4等)来做,密码就是TLS Handshake协商获得的.所以说,
              对于每个与Server通信的Client它们之间通信的密码都是唯一的.

    以上就是HTTPS底层的工作过程,仅为个人理解,故仅做参考.

  • 相关阅读:
    无法连接到已配置的开发web服务器
    Java开发命名规范总结
    java包名命名规范[【转】
    github远程建了分支,本地看不到的问题
    git远程删除分支后,本地git branch -a 依然能看到的解决办法
    git主要操作命令
    Ant之build.xml配置详解【转】
    git合并指定文件到另一分支
    java最简单实现Log打印和生成日志文件
    SCF: 简单配置门面[转]
  • 原文地址:https://www.cnblogs.com/wn1m/p/10883236.html
Copyright © 2020-2023  润新知