白话HTTPS(上)

0

课前提问

文章开始前先问大家几个问题,如果不明白的或则理解不透彻的,看完这篇文章就都能明白了。

0、https是指一个协议吗?它的出现是为了解决什么问题。

1、大家都知道https 是 safe 的http,那https相比http安全在哪呢?

2、对称加密,非对称加密的原理是什么?

3、非对称加密的公钥,私钥听过没?他们为什么能用一个密钥加密,然后用另一个密钥解密。

4、他们分别用在https的哪个阶段,这样用是基于什么考虑?

引言

公司前段时间要求把我们应用使用的的网络链接全部都从http换成https,之所以这么要求的原因是市场反馈有用户的机子系统升级一直卡在某个百分比上不去,相关的同事分析是原来的请求被域名劫持了(具体细节不大清楚,听了个大概)。

那么这个域名劫持是怎么发生的呢?http 为什么不安全?HTTPS 为什么是安全的?

先看下我们的http请求报文格式。

file

众所周知http报文都是明文传输,也就是说http的报文的全部内容都是可见的,比如里面的请求方式和服务器地址。

我们访问某个域名是需要很多个中间服务器路由转发的,就拿桌面接口来说,在一次trace中到达目的地址服务器需要14个节点,在这中间每个节点都可以通过技术手段篡改报内容,来做一些坏事。

file

一次请求的http报文大概长这样:

file

如上图:格式固定,内容可见。很容易被被更改利用。

除了恶意篡改数据包内容之外,常见的就是域名劫持了。

当我们在电脑浏览器中输入一个域名比如 www.test.com

首先根据输入的网址,提取出域名www.test.com

  1. 如果你在系统中配置了 Hosts 文件,那么电脑会先查询 Hosts 文件,看这个www.test.com 是否已经在Hosts 里面有了对应的记录。如果有,直接就可以拿到该记录中的 IP地址,流程结束。
  2. 如果 系统Hosts 里面没有这个别名,那么电脑会看你有没有设置域名服务器(DNS 服务器)。如果你的系统没有设置域名服务器,那就莫得办法,浏览器直接会报错,说网站的域名无法解析。流程结束。
  3. 如果你设置过“域名服务器”,那么电脑会向这个域名服务器发送一个域名查询(DNS query)的请求,然后等候域名服务器的回应。

本地域名服务器收到来自客户端的请求。缓存了一域名与之对应IP地址的映射格。如果能找到www.bbkcom ,它直接就返回IP地址。如果没有,本地DNS会以自顶向下,以根域名服务器 、顶级域名服务器、权威域名服务器、的顺序自顶向下查找,直到找到为止。

file

  1. 如果域名服务器始终没有回应(比如域名服务器崩了,或域名服务器的IP填错了,或请求被 拦截了),那么电脑莫得办法(浏览器会报错)。
  2. 如果域名服务器回应了,那么你的电脑就可以根据域名服务器的应答信息,得到该域名的 IP地址。之后浏览器就会向这个 IP地址 对应的 Web 端口发送 HTTP 请求。

整体流程如下:

file

了解了上述DNS流程我们再来聊聊啥是“域名劫持"?

说白了,在上述流程中,我们解域名对应的地址过程中,本地DNS缓存,或者DNS服务器上的记录被人为修改了,导致我们拿不到域名正确的IP地址结果,这种情况称之为“域名劫持"。

下面是我们的正文。

正文

1 什么是数据安全?

说了那么多http 不安全的部分 ,我们来聊聊为什么HTTPS是安全的?

首先我们需要了解安全的定义,在网络世界中,什么样的数据才是安全。

安全的数据需要同时具备了机密性、完整性、身份认证、不可否认这四个特性。

1、机密性

是指对数据进行加密,只有通信双方能看得懂数据内容。

2、完整性

是指数据在传输过程不多不少也没有被更改。

3、身份认证

是指确认通信两端,证明你是你。他是他。

4、不可否认(Undeniable)

也就是说话算法。

明确了以上概念,我们继续聊聊HTTPS是如何做到信息安全的。

HTTPS 全称是超文本传输安全协议( Hypertext Transfer Protocol Secure,),意思就是“HTTP over SSL/TLS",即运行在了安全的SSL/TLS协议上HTTP)。

file

SSL 全名安全套接层(Secure Sockets Layer),在1999年把它改名为TLS(传输层安全,Transport Layer Security)所以对于现在来说常常讲的SSL 和TLS其实是同一个东西。

目前应用的最广泛的TLS是1.2。

TLS囊括了记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

客户端和服务器在使用TLS建立连接时需要选择一组恰当的加密算法来实现安全通信,这些算法的组合被称为“密码套件”(cipher suite,也叫加密套件)。

下图是OkHttp源码截图 里边支持的密码套件

file

这一长串的英文虽然看起来有点花里胡哨,但其实是有规则在里边的。

密码套件格式是“密钥交换算法+ 签名算法+对称加密算法+ 摘要算法”

(ECDHE RSA AES_256_GCM SHA384)

比如图片中圈出来的套件意思是“握手时使用ECDHE算法进行密钥交换,用RSA签名和身份认证,握手后的通信使用AES对称算法,对称加密密钥长度256位,分组模式是GCM,用摘要算法SHA384进行消息认证和产生随机数。”

在理解了密码套件的格式的基础上,再看那张图片,其实会发现每种算法常使用的就那么几种。

这些套件以及里面涉及到的各种算法是后面握手和传输中使用的,我们一步一步来看。

2 https如何实现机密性

2.1对称加密和非对称加密

前面我们讲到,数据安全的第一个要求就是机密性。

机密性大家都懂,直白地讲就是让传输的数据让别人看不懂。

2.1.1 对称加密

我们来看一个小小的故事。

不知道大家有没有看过斯巴达勇士,

在公元前405年,雅典和斯巴达之间的伯罗奔尼撒战争中,斯巴达军队截获了一条写满杂乱无章的希腊字母的腰带,斯巴达在将军在百思不得其解之际,胡乱将腰带缠到自己的宝剑上,不想带上那些杂乱无章的字母,竟组成了一段文字。从而得知了重要的军事情报。为后面战争的胜利奠定了基础。

这种加密方式后来也被称为斯巴达密码棒。

加密方式就是把长带子状羊皮纸缠绕在圆木棍上,然后在上面写字;解下羊皮纸后,上面只有杂乱无章的字符,只有再次以同样的方式缠绕到同样粗细的棍子上,才能看出所写的内容。

这个棒子大概长这样子:

file

我们现在常常把加密方式分为对称加密和非对称加密。

对称加密很好理解,大部分古典密码学(什么凯撒密码,斯巴达密码棒都是对称加密)比如上面的例子,在木棍上写的羊皮纸打开后要缠回到同样形状大小的木棍才能重新看得懂,有点解铃还须系铃人的意思。就像我们平时的开门锁门,因为用的是同一把钥匙。还有之前很火的英剧神探夏洛克就有个很常见的套路,比如说得到一串神秘的字符

比如B31C12D5E6

这其实是凯撒密码的变形,原理是这串字符可以是对应圣经或者某本书的页面,和单词。比如B 是 英语字母的第二个,对应是第二页的意思,后面紧接的数字31则是第31个单词的意思,以此类推,这串字符对应找出四个单词组成一句话然后成为破案的关键。

对称加密核心概念就是加密解密都是用同样的秘钥。

2.1.2 非对称加密

相对于对称加密,非对称加密的概念就有点反直觉了。

对称加密算法在加密和解密时使用的是同一个秘钥;而非对称加密算法需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。

在理解公钥私钥这两个概念之前,我们先想想为什么需要非对称加密,全程用对称加密不好吗。

主要原因是对称加密无法解决秘钥传输的问题,一入网络深似海,网络世界不像现实中可以脸贴脸,手把手地把秘钥交给别人,但是你要通信,你要让别人看得懂你加密的信息,你就得必须把秘钥传送给别人。

而非对称加密可以解决这个问题。

看下面非对称加密的通信模型:

file

A和B通信,A和B同时拥有各自的公钥和私钥,公钥A 私钥A 和 公钥B 私钥B。

1、每个端和对方通信都用对方的公钥加密,例如A 发送给B HelloB 这句话是用B的公钥加密。

2、每个端收到信息都用自己的私钥解密,例如B 收到 hello B 就用自己的秘钥B解密。

3、反过来B和A通信也是如此。

在这上面流程中公钥是可以在网络中传输的,让对方和自己发消息加密用得,而私钥只有自己知道自己保存,自己解读别人发送给自己的加密信息用的,并不用传输,从而避免了传输过程被窃取的风险。

但这里非对称加密还是有反直觉的点,为什么非对称加密可以用公钥加密然后用私钥解密?

用公钥加密的数据不能用公钥解密吗?因为在我们常规概念中一把钥匙开一把锁,用这把钥匙锁上的锁当然也能用这把钥匙打开。难道我用这把钥匙锁上的锁完了用这把钥匙打不开了?

为了更好地理解这一个概念,下面我想请一个观众配合我玩一个小魔术:(此处由现场表演转成文字描述)

1、在脑海想一个三位数。想好后把这个数字输在计算器上给大家看,别给我看。
2、把这个三位数乘以91给大家看,然后把末三位数字告诉我。

我可以通过以上的信息就判断出你所想的数字是什么?

其实这个魔术的道理很简单,91乘以11等于1001,而任何一个三位数乘以1001后,末三位显然都不变(例如123乘以1001就等于123123),观众把结果的后三位告诉我,我再把这个结果乘以11,就相当于把观众原来想的数乘以1001,此时结果的后三位就是观众想的数。

以此类推只要构造两个素数乘积是X001,就可以达到加密三位数的效果。

上面的通信流程可以看做一次极简非对称加密通信过程:

1、我暴露给你们的公钥是91 ,你们要和我通信的数字乘以91再选取末三位就是加密过后的数据大家都看不懂,用公钥也无法解密。

2、我拿到加密的数据之后,用自己的私钥(11)进行解密就可以得到原文。

3 上面的公钥91可以在网络上传播,被别人知道也不影响,私钥11从未传播不存在因为网络传播被窃取的风险。只要我这个客户端不被攻破,那么这次通信就是安全的。

知道原理后,我们可以设计一个范围更大的非对称加密解密系统。

比方说,任意一个数乘以400000001后,末8位都不变,而400000001=19801*20201,于是给你个公钥19801,我用私钥20201解密,这样我们又得到一个八位数的非对称加密系统。

甚至可以构造得更大一些:

4000000000000000000000000000001=1199481995446957*3334772856269093

这样我们就成功构造了一个30位的加密系统。

基于以上的小魔术我们应该对非对称加密有了个立体的认知。

2.2单向函数

非对称加密都是基于一个数学概念- 单向函数。

根据百度百科:
单向函数(One-way function)是一种具有下述特点的单射函数:对于每一个输入,函数值都容易计算(多项式时间),但是给出一个随机输入的函数值,算出原始输入却比较困难)。

给大家举个例子,比如:

21 可以因式分解为哪两个素数? 3乘7
51 可以分解那两个素数 3 乘 17
那么更大一点的391 呢 ? 就不好想了, 可能得一个个穷举
结果是17 乘 23.
再大大大一点的比如2981231823172381982371981 呢?用计算机穷举也要花点时间。

我们知道两个素数的乘积,但反过来根据素数的乘积推算这两个素数却很难。

上面的难题就是大素数之间的乘积难以因式分解问题。常用的非对称加密算法比如RSA算法,就是基于这个原理来设计的。现在普遍要求安全的RSA秘钥长至少要2048位。

所以实际上的秘钥可能长这样子

12387123981723981724039123091283912803182938109810982392132912319203819231293101811 。。。(以下省略两千位数字)

还是比较安全的。

另一个常见的非对称加密算法ECC(Elliptic Curve Cryptography),它基于“椭圆曲线离散对数”的数学难题,本质上也是一个单向函数,使用特定的曲线方程和基点生成公钥和私钥,子算法ECDHE常用于密钥交换,ECDSA常用于数字签名。对比RSA算法复杂度更高,所需要的秘钥长度更短。

具体的实现细节有兴趣的同学可以Google关键字自行了解,在理解原理的基础上去看设计就会容易理解得多。

2.3混合加密

非对称加密虽然安全,但是每次通信都要和很长的秘钥一起运算,运算速度相比对称加密来说非常缓慢,相差几百倍以上。

所以TLS里使用的混合加密方式是把对称加密和非对称加密结合起来呢,各取所长:

在通信刚开始的时候使用非对称算法,比如RSA、ECDHE,首先解决密钥交换的问题。

然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥通常很短,只有16字节或32字节,用非对称加密算法交换对称加密算法的秘钥也不会慢到哪里去。

对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续通信就不使用非对称加密,全都使用对称加密。

HTTPS的对称加密 非对称加密 以及 混合加密其实就是这么回事。

由于对称加密和非对称加密和后面要讲的内容关系十分密切,消化这一块内容对理解HTTPS方方面面有很大帮助。所以今天的核心内容是讲明白这一块。今天的分享先讲到这,下次再继续聊明白HTTPS 如何保证数据完整性,身份认证,以及摘要算法、数字签名, 数字证书,都是些什么如何产生与使用, 在HTTPS中 扮演什么角色 以及完整的握手流程。谢谢大家。