HTTP学习笔记2_HTTPS

一.HTTP

HTTPS的出现是为了弥补HTTP的缺点:

  1. 通信内容可能被窃听

    HTTP使用明文通信(不加密),内容很容易被窃听,HTTP本身不具备加密的功能,无法对通信内容进行加密

    不加密其实本来不是什么大问题,但TCP/IP的工作机制致使整个通信线路上的任意节点都能拿到报文,而且Internet中的任意一个节点都有可能成为中转站,所以加密变得要紧了

    加密不能阻止窃听,窃听者还是可以轻易拿走(加密过的)报文,但加密能让报文失去价值(只要保证在一定时间内窃听者无法解密就可以了)

  2. 身份可能遭伪装

    HTTP协议没有身份验证机制,不会对通信双方进行确认,所以可能存在“假客户端”、“假服务器”。此外,DoS(Denial of Service)攻击的存在也是因为HTTP没有身份认证机制

    由值得信任的第三方机构提供数字证书即可,证书既可以用来表明服务器是“真服务器”也能用来表明客户端是“真客户端”,只需要分别持有各自的证书

    证书这么好用,却没有普及,是因为第三方机构提供的证书是收费的(每张几千到十几万RMB不等)。服务端好说,一张就好,但海量的客户端证书就很昂贵了,一般应用无力支撑,所以只有网银之类的应用需要安装客户端证书

    P.S.至于证书是什么,具体工作机制是什么,下面会有详细解释,此外,还有不需要借助第三方的“自签名”,长远来算很划算,但一般企业也玩不起

  3. 通信内容可能被篡改

    HTTP无法证明报文完整性,不能确定报文在路上有没有被拦截篡改,所以存在MITM(Man-in-the-Middle,中间人)攻击

    现有的防篡改方法有MD5、SHA-1等散列值校验以及用PGP(Pretty Good Privacy,完美隐私)创建文件的数字签名等,都不好用,因为必须由客户端用户自行检查篡改是否发生,浏览器无法自动完成,很不方便。而且,即便这样做了,还是无法100%避免通信内容被篡改,因为PGP和MD5本身也可能被改写

二.数字证书与混合加密

1.混合加密

理解HTTPS前有必要先理解数字证书是什么东西,而在这之前应该知道3种加密方式:

  • 对称加密(共享密钥加密):最简单的加密方式,通信双方持有相同的密钥

    发送方用密钥加密后把密文发送给接收方,接收方拿到密文后用同样的密钥进行解密得到明文,反之亦然

    缺点:密钥无法安全交给对方(在网络通信中,信息安全只能通过加密来保证,如果能把密钥安全送达,那就意味着其它信息也能安全送达了)

  • 非对称加密(公开密钥加密):密钥成对使用,分为公钥和私钥(公钥是公开的,私钥不公开)

    公开公钥,发送方用公钥加密,接收方拿到密文后用私钥进行解密得到明文,反向通信时发送方用私钥加密,接收方用公钥解密即可

    缺点:与对称加密方式相比,分对称方式加密解密过程有更大的开销(要保证用密文+公钥无法推算出私钥,就需要复杂算法的支持)

  • 混合加密(综合以上两种方式):用非对称方式传递共享密钥,然后用对称方式通信

    对称方式开销小,最大的问题是无法保证密钥被安全送达,而非对称方式恰好能够解决密钥共享的问题,所以有了混合加密

    先用非对称方式传递共享密钥,保证了密钥能被安全送达,再用对称加密方式通信,避免了使用非对称方式通信的开销,完美了

    HTTPS采用的就是混合加密方式

2.数字证书

数字证书其实是被加密过的公钥,这份证书能够同时证明证书主人(数字证书认证机构)和公钥主人(服务器/客户端)的身份。具体原理如下:

背景:服务端S决定对通信进行加密,以保证客户在线办理业务时的信息安全

  1. 把S的公钥发布出去(告诉客户端C)

    怎么发布是个问题,因为C收到公钥后不能确定公钥是不是真的(无法证明S的身份),万一是别人恶意发布的就麻烦了。

    如果C只收到1个假公钥,可以用该公钥对请求进行加密,然后S发现无法解密后拒绝请求就好了,只用多发一个请求就能解决问题。但如果C收到100个假公钥呢,继续一个一个验证吗?

    当然不行,这时就需要借助第三方数字证书认证机构了

  2. S请数字证书认证机构CA帮忙发布公钥,以证明这个公钥是真的(证明S的身份)

    CA收了S给的小费后,用自己的私钥对公钥进行加密,得到的这个密文就是数字证书。再把这个证书交给S,说以后只要把证书给C,C就知道你是真的了(P.S.其实“证书”非常贴切,S为了证明自己的身份,去找CA办身份证,CA给盖了个红戳,这就是“证书”)

    等等,为什么C一看证书就知道是不是真的?万一证书是假的呢?怎么证明证书的有效性?

    为了避免这样无休止的证明下去,浏览器中内置了CA的公钥,C一拿到S给的证书,马上取出CA的公钥对证书进行解密,如果证书是真的,C就能拿到S的公钥(证书是用CA的私钥对S的公钥进行加密的产物,解密当然能得到S的公钥),这不仅证明了S的身份,还证明了CA的身份

    注意,浏览器内置CA公钥是无偿的,浏览器为了适应市场需求必须把各大CA的公钥内置到浏览器中,而CA不用给浏览器供应商小费,为什么一直强调钱?

    为了说明证书是收费的,而且不便宜,前面提到了:

    证书这么好用,却没有普及,是因为第三方机构提供的证书是收费的(每张几千到十几万RMB不等)。服务端好说,一张就好,但海量的客户端证书就很昂贵了,一般应用无力支撑,所以只有网银之类的应用需要安装客户端证书

  3. C拿到S的公钥后,加密发送共享密钥(Pre-master secret随机密码串)

  4. S用私钥对收到的共享密钥进行解密,得到共享密钥,然后开始快速安全的通信

上面的例子是服务端证书,用来证明服务端的身份。同理,也可以有用来证明客户端身份的客户端证书,比如网银的U盾

因为证书价格不菲,所以也只有网银之类的东西有客户端证书

3.自签名

知名CA机构的证书是比较昂贵的,所以一些企业决定自己搞证书(自己当CA),这就是为什么有时候浏览网页时候浏览器会弹个窗口提示该站点的证书不可信,是否继续访问……其实是因为浏览器没有内置该站点的公钥,结果就是浏览器看到了证书,却无法证明证书的真假

所以自签名没什么意义,并不能提升通信安全性,除非自己当CA已经做大成了知名CA,公钥被浏览器收藏了才算

自签名的好处是证书很廉价,因为只要具备了生产条件,可以产出无限多个证书,随便发。

但自己当CA不是那么简单,CA要求具备非常可靠的安全防护条件,所以知名CA对证书收费也是合理的,用来维护证书颁布系统的安全

三.HTTPS

1.HTTPS是什么?

HTTPS = HTTP + 加密 + 认证 + 完整性保护

      = HTTP + (SSL + TLS实现的)加密 + (数字证书实现的)认证 + (数字证书实现的)完整性保护

HTTP = TCP + IP

HTTPS = SSL + TCP + IP

P.S.TLS是以SSL为原型开发的协议,有时候统一称为SSL,所以最后一个等式中没有TLS

注意:

  1. HTTPS比HTTP慢2到100倍

    一方面SSL通信本身慢(SSL的传输处理);另一方面SSL开销大,处理速度慢

    没有根本性的解决办法,可以用SSL加速器这样的(专用服务器)硬件来提升SSL处理速度

  2. HTTPS并不是一直进行加密通信

    只有在传输敏感信息时才加密(用HTTPS),其它时候仍然用HTTP,可以提升通信速率并减少开销

2.加密方式

  • 通信的加密

    HTTP没有加密机制,所以引入SSL(Secure Sockets Layer)和TLS(Transport Layer Security)实现对通信的加密

    用SSL建立安全通信线路之后,在这条线路上进行HTTP通信,这样的方式被称为HTTPS(HTTP Secure,超文本传输安全协议)或者HTTP over SSL

  • 内容的加密

    对报文主体进行加密,当然,这需要客户端、服务器的双向配合(都要支持加密/解密功能)

    而且只对内容加密并不安全,因为报文首部没有加密,HTTP首部注入攻击可破之

3.身份认证方式

  • BASIC认证

    服务端返回401响应要求身份认证,客户端把用户名和密码用Base64编码后发送给服务端,服务端根据这个字符串进行身份验证,成功返回200,否则继续401

    Base64编码并不是加密,与明文传输没什么区别,HTTP传输极不安全,所以不常用

  • DIGEST认证

    既然BASIC认证用Base64编码传输密码不安全,那么就对密码进行简单加密(对密码做MD5运算)

    能防止窃听,但无法防止身份伪装,也不常用

  • SSL客户端认证

    用证书可以防止身份伪装,客户端把客户端证书发送给服务端,服务端取出客户端的公钥,然后开始HTTPS通信

    但客户端证书也是收费的,所以也不常用

  • 基于表单的认证

    最常用的是基于表单的认证,安全性取决于Web应用程序

    一般会用到MD5 + salt(加盐的MD5),这里有必要说明一下:

    salt其实是服务端生成的随即字符串,保存在服务器数据库里

    新用户注册时生成一个与用户ID对应的salt串,然后把salt串与用户的明文密码进行拼接,对拼接结果做MD5,结果作为用户表里该用户的密码串

    登录时查表取出用户对应的salt,与明文密码串拼接得到密码串,再查用户表取出该用户的密码与之对比,验证身份

    加盐其实是为了方式查表破解MD5,不加盐的MD5用彩虹表很快就能查表破解,加盐后就减少了密码特征(用户表里明文密码相同的用户的密码串不同)

    关于MD5 + salt有一篇非常好的文章,请查看乌云:加盐hash保存密码的正确方式

四.HTTPS通信过程

  1. 客户端通过发送Client Hello报文开始SSL通信

    报文中包含客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表(支持的加密算法及密钥长度等等)

  2. 服务端可进行SSL通信时,以Server Hello报文作为应答

    和客户端一样,在报文中包含SSL版本以及几码组件。服务端的加密组件内容是从接收到的客户端加密组件内筛选出来的

  3. 服务端发送Certificate报文

    报文中包含公开密钥证书

  4. 服务端发送Server Hello Done报文通知客户端

    最初阶段的SSL握手协商部分结束

  5. SSL第一次握手结束之后,客户端以Client Key Exchange报文作为回应

    报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密

  6. 客户端继续发送Change Cipher Spec报文

    该报文提示服务端,在此报文之后的通信会采用Pre-master secret密钥加密

  7. 客户端发送Finished报文

    该报文包含连接至今全部报文的整体校验值,这次握手协商是否能够成功,要以服务端是否能够正确解密该报文作为判定标准

  8. 服务端同样发送Change Cipher Spec报文

  9. 服务端同样发送Finished报文

  10. 服务端和客户端的Finished报文交换完毕后,SSL连接算建立完成

    当然,通信会受到SSL保护,从此处开始进行应用层协议的通信,即发送HTTP请求

  11. 应用层协议通信

    发送HTTP请求/响应,会附加MAC(Message Authentication Code)报文摘要,检查MAC能够得知报文是否被篡改,以保护报文的完整性

  12. 最后由客户端断开连接

    发送close_notify报文

  13. 断开TCP连接

    发送TCP FIN报文关闭TCP通信

参考资料

  • 《图解HTTP》

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code