HTTPS 概念
这一篇文章介绍了HTTP1.1的缺点,以及SSL、TLS的历史,之后介绍了有关SSL加密的主要加密方案:公开密钥加密 和 共享密钥加密,最后简单介绍了HTTPS的交互过程、
如何定义“安全”
定义安全靠的是下面几点:
- 完整性:也叫做数据一致性,指的是传输过程自出发到接受的信息是一致的。机密内容可以被黑客替换或者删除添加,一旦被接受并且核验通过,会带来大问题。
- 机密性:对于数据保密之后,只有信任的对象可以访问,其他人哪怕拿到保密信息,也无法识别出里面的内容。
- 身份认证:身份认证需要明确的证实对方身份,比如报警的时候要求警察出示身份证据,并且看到盖章许可文件才允许进入,不然黑客冒充的,不管怎么防都没有用。
- 不可否认:指的是发生的事情不能进行诋毁,某一项操作必要在通信完成之后产生一定影响。否则就是类似访问一个看起来极其逼真的网站但是却是一个空壳,空壳后面直接把你的个人信息套走。
HTTPS 解决的问题
HTTPS 解决了什么问题?我们介绍HTTP的主要问题,以及如何解决这些问题的。
HTTP的主要问题:
- 信息加密:保证敏感信息不会被窃取。
- 身份校验:数据完整性保证,数据无法篡改,篡改之后无法正常使用。
- 身份证书:证明服务端是真实具备公信力的。
如何解决这些问题:
- 信息加密:使用双层加密机制,连接使用非对称加密,同时在连接之后使用对称加密,双保险的混合加密保证安全。
- 摘要算法:保证数据的完整性,TLS协议主要推荐使用SHA-2“集合”下面的加密算法,相当于给数据生成一个解锁指纹。
- 身份证书:服务器公钥放入数字证书,自己再使用私钥再加密一遍进行传输,防止被人冒充。
除了上面三点之外,还有一点“不可否认“,但是严格意义上并不是HTTPS本身的“功劳”:
- 不可否认:CA证书颁发机构本身具备权威及公信力,一旦服务端被声明存在,那就是一定存在。
HTTP和HTTPS的区别
HTTP是明文传输,在传输一些敏感信息的时候可能存在窃取信息的情况。 HTTP连接相对效率更高,因为它只需要三次握手就是完成连接操作,而TLS/SSL需要多加入四次握手才能完成连接。HTTPS 整体需要耗费更多的连接时间。 HTTP的端口默认是80,SSL默认端口为443。 HTTPS客户端发送公钥需要向CA申请数字证书签名,保证公钥安全传输到客户端。
SSL/TLS 历史
TLS含义
TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。
浏览器建立SSL协议连接,实际上就是使用多个子加密协议组合,最终选择合适的加密算法进行数据安全传输,这种算法组合本身被叫做“密码套件”。
此外TLS 的密码套件命名看起来很长,但是实际上非常规范,格式很固定。基本的形式是**“密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法”。**
比如:ECDHE-RSA-AES256-GCM-SHA384
所表示的含义为:
“握手时使用 ECDHE 算法进行密钥交换,用 RSA 签名和身份认证,握手后的通信使用 AES 对称算法,密钥长度 256 位,分组模式是GCM,摘要算法 SHA384 用于消息认证和产生随机数。
数字加密历史
数字加密的是在计算机出现以及专业的密码机出现之后诞生,但是实际上密码学有了上千年历史,下面我们依照《HTTP权威指南》中14.2节的介绍大致回顾数字加密历史。
数字加密的发展大致经历了下面的过程:
密码
密码通常是一套固定编解码规则的加密信息,被编码之后文本信息被叫做密文。比如我们用AAA代替阿拉伯数字1,BBB代替阿拉伯数字2,C…这样的规则组织出一套针对阿拉伯数字的加密,在加密的时候用密文进行替换。
- 加密前:9112955
- 加密后:IIIAAAAAABBBIIIEEEEEE
密码机
早期的密码都是十分简单的,掌握规律之后很容易破解,而密码机是把加密规则从明文本身“剥离”的一种改进。原本针对一套文本的加密规则,后面使用了专门负责加密的密码机,负责更加复杂的加密算法处理,这些规则加解密单靠人力对抗密文已经比较难,所以安全性更高一层。
密钥加密
但是随着技术发展,人们发现使用密码机加密有一个漏洞,一旦密码机被盗或者被仿制,那么加密规则就失效了,经典案例来自二战时期的德国密码机被图灵攻破。
所以在二战之后又发明了一种可以自由改动加密规则的带有号码盘的密码机。简单来说就是给密码机本身又上了另一套加密规则。
被加锁之后的密码机,需要特殊的钥匙解锁才能正确的翻译密文,否则会被翻译乱码或者毫无规律的解密信息,密码密钥会让多个密码机看起来像是虚拟的密码机一样,每个密码机又不同的数值,他们需要配合在一起才能正常解密加密信息。
这就有点像是把一个解密的钥匙掰成很多份,每份钥匙上又有很多杂乱无章的齿,所以难以破解。
密码和密钥很容易被混为一谈,其实他们是类似“包装”的关系,密钥是对于加解密规则进行“乱序”,保护密码和加解密规则本身的手段,目的是即使被拿到加解密方法也没法正确的还原解密之后的信息。
数字密码
数字计算围绕两个主题:
- 计算机的飞速发展,复杂的编解码规则实现。
- 超大密钥难以破解,可以从一个加密算法产生数万亿的虚拟加密算法,组合出不同的密钥。密钥越长,随机猜测的难度越大。
通常编解码的函数为反函数,也就是说通过加密函数加密 P,再通过解密函数解密 P,会得到原始报文P。下面是关于数字密码加密的例子:
给定一段明文报文 P、一个编码函数 E 和一个数字编码密钥 e,就可以生成一段经过编码的密文 C。 通过解码函数 D 和解码密钥
d,可以将密文 C 解码为原始的明文 P
对称加密
密钥和密码的配合,最初形成是类似原有密码的对称加密手段。对称加密说的是所用的加密密钥和解密密钥都是同一个,比较流行的算法包裹:DES、Ttriple-DES(3DES)、RC2和RC4、ChaCh20、AES。
但是需要注意RC4(RC2)、DES、3DES,这几种对称加密方法都是不安全的,通常禁止使用,所以还剩下AES以及ChaCh20。
- AES: 的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是 128、192 或 256或者更长。
- ChaCha20: 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,在ARMv8引擎升级之后,AES也飞速提升被反超。所以现在来看虽然优势不大,但是依然不错的一个算法。
因为是对称密钥加密,所以只需要双方持有相同的密钥,并且协商好密码的加解密规则,就可以完成对称加解密。
密钥长度的重要性
目前大部分情况下除非完全自己写加解密算法,否则大部分的加解密的密码算法都是“透明”的,所以现在安全的反倒是密钥。通常的加密算法破解手段是利用穷举组合密钥的方式去“试”,这也意味着越长的密钥越安全,但是所需要的计算机资源相对也会更多。在密钥出现的早期,很短的密钥就可以满足加密算法的保护,但是到了现在随着超级计算机出现以及CPU效率的提升,密钥的长度已经来到了SHA-256。
关于密钥长度以及破解需要的代价对比,哪怕是1995年的数据,放到现在依然有一定的价值,因为目前SHA-256依然没法在短时间破解。
对称加密的最严重问题除了是密钥本身容易,还有一点是密钥共享和本身的管理问题,因为共享密钥需要传给ABCDEFG,一旦出现更改又要重新传一遍,这导致有的人用的旧密钥,有的使用新密钥,这样做法管理起来非常麻烦。
公开密钥加密
共享密钥本身的管理问题以及安全问题,后续出现了使用非对称的加密方案,所谓非对称加密就是说加密的密钥是公开对外开放使用的(不用向共享加密一样藏着掖着),所有人都可以拿到这份公开密钥加密内容,但是加密过后的信息,除了发布者知道之外都是保密的。
公开密钥加密在共享加密的基础上做了升级,改进了密钥数量膨胀问题。公开密钥架构(Public-Key Infrastructure,PKI)标准创建工作已经开展十多年了。因为非对称的加密算法要难非常多,所以在TLS里面可以看到的有下面几种:
- DH
- DSA
- RSA
- ECC
在这几个加密算法当中RSA可能更熟悉一些,它的算法思路是“整数分解”的数学界难题,意思是说两个超大素数的乘积作为加密材料,要想通过公钥推算出私钥是非常难的。
在过去RSA的长度为1024、到了现在则是2048,因为1024长度已经不安全的,往后可能需要更长的长度才能确保安全。但是RSA到了现在实际上也已经不安全。
ECC(Elliptic Curve Cryptography)是继广泛流传的RSA之后的一种“椭圆曲线离散算法”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。
ECC目前比较常用的两个曲线是 P-256(secp256r1,在 OpenSSL 称为 prime256v1)和 x25519。P-256 是被 NIST(美国国家标准技术研究所)和 NSA(美国国家安全局)推荐使用的曲线,X25519则是被认为是安全的、快速的曲线。
ECC 的椭圆曲线实际上并不是椭圆的,而是方程类似椭圆的周长公式,实际的形状更像是两个抛物线。
ECC与RSA对比
首先,针对RSA的算法公认的破译难度是亚指数级别的,而ECC的破译难度是指数级别的。其次ECC所需的加密密钥长度要比RSA缩短好几倍,比如1024的RSA相当于160位的ECC,224 位的 ECC 则相当于 2048 位的 RSA。因为密钥的长度合适,所以十分受欢迎。
需要注意虽然ECC很快了,但是和对称加密的几个算法比起来还是差了好几个量级,比如下面的测试报告:
aes_128_cbc enc/dec 1000 times : 0.97ms, 13.11MB/s rsa_1024 enc/dec 1000 times : 138.59ms, 93.80KB/s rsa_1024/aes ratio = 143.17 rsa_2048 enc/dec 1000 times : 840.35ms, 15.47KB/s rsa_2048/aes ratio = 868.13
通过对比可以看到,AES加密是非常快的,只需要纳秒级别的时间,而2048位的RSA需要它的几百倍。
所以这也是为什么TLS需要使用对称加密和非对称加密混合使用的根本原因,如果全部按照非对称加密传输,那么页面的传输响应时间可能要凭空多出几秒,这对用户来说是无法接受的。
数字签名
数字签名是除开对于报文加解密的另一种思路,签名的目前是保证数据一致性和防篡改。同时签名可以数据的所属来源是否真实可靠。
产生数字签名的方式实际上还是 公开密钥加密,但是把思路反过来了,数据是通过私钥进行加密的,只有公钥可以解锁。
数字签名通常会在传输之前双方各持有一份,传输的内容在中间被破解并且被篡改,在收到后可以先拿公钥解密验证一下,然后再取出数字签名匹配一下,如果其中任意一方匹配不上,那就可以说明传输的数据被人篡改了,又因为私钥是保密的,黑客没法伪造签名,只能干巴巴看着到嘴的肉飞走~~
数字签名通常是使用单向加密的摘要算法,摘要算法主要负责计算内容的哈希值(HMAC),这个哈希码是唯一的,并且无法反向推导。
我们可以把摘要看作是一个指纹,在哈希算法中可以保证指纹不会被篡改,但是这里显然有一个漏洞:虽然不能改签名,但是可以换签名和内容。
所以单纯的摘要算法只能保证数据完整性,但是不能保证数据安全,为此就需要加入非对称加密算法,加强双向数据的传输。
非对称加密通常需要两个钥匙,一把私钥由自己保管,公钥可以对外开放使用。密钥可以双向破解,也就是可以私钥加密,公钥解密,也可以公钥加密,私钥解密。
处理方式不同,其实现的效果也不一样:
- 公钥加密,私钥解密(机密性):公钥加密的数据只能被私钥破解,这样保证数据的安全。
- 私钥加密,公钥解密(完整性):私钥加密的数据只能被公钥解析,私钥加密的数据一旦被篡改或者替换,公钥解密之后可以证明数据的是否符合要求。
数字签名实际的使用过程是这样的:【(私钥加密+ 摘要算法),公钥解密 】,需要注意私钥加密的并不是原始内容,而是被摘要算法计算过的指纹(也就是HMAC值)。
这样也就实现了双保险,但是这样的双保险还是存在风险,我们可以看看下面这个攻击过程:
- 客户端向服务端索取公钥进行通信,此时黑客从中间插手,伪造一对公钥和私钥,然后继续向服务器获取公钥。
- 服务器误以为是客户端发来的,所以果断加密信息然后返回公钥。此时黑客拦截,黑客压根不用管怎么解密这些内容,此时它用自己的【私钥+数字签名】伪造一份数字签名,然后发给客户端。
- 客户端拿到被伪造的公钥,使用公钥加密后续通信使用的对称密钥,传给服务端。
- 中间人截取请求,用自己的私钥解密信息, 拿到对称密钥,然后仿照客户端的请求使用真实公钥加密自己伪造的对称密钥。
- 服务端使用私钥解开之后,得知对称加密算法,然后开始和黑客进行正常通信。
- 黑客鸠占鹊巢,成功破解,这时候黑客既可以利用伪造的身份从服务器获取信息,也能伪装成服务器向客户端发送一些虚假信息,这样实在是危险。
为了简化理解,我们可以简单把上面的步骤抽取出下面几个关键点。
数字签名只解决了关于安全的两个方面问题,所以实质无法保证安全通信。所以很无奈,既然怕你们乱来,那只好设置一个授权机构,以后客户端可以找我核实对方身份,而服务端需要我这里的文书才算是真的认可。
数字证书
数字证书是无止尽加解密的最后一道关口,数字证书通常包含了某些组织或者某些公司的相关信息。数字证书也可以看作是数字签名的进步版本,也是解决无穷无尽的加密套娃的最终解决方案。
数字证书的概念在生活中比较常见,可以想象为美国电影里面搜捕公民的房间需要向上级申请搜捕令才能进入。
数字证书是目的防止HTTPS加密中密钥被篡改的“无限套娃”加密的问题,因为数字签名和密钥信息需要传输,中间必须要有一个足够可靠的第三方伙伴证明。
这个认证过程被称之为CA认证,客户端收到包含CA数字证书签名的服务端的请求之后(私钥加密),通过用浏览器内置的CA证书公钥解密,只要证书通过校验,就可以认为服务端是稳定的。
通过上面的解释我们知道,客户端和服务端的在SSL握手中的非对称加密方法是是公钥加密,私钥解密,数字签名的摘要作为防篡改校验。
而数字证书的用法则是把这个过程反过来,变为私钥加密、公钥解密。并且利用需要数字证书给数字签名再加个章,这样的效果相当于是一个三方校验。
所以你数字证书的授权机构怎么保证自己靠谱呢?我们从下面几个点来进行说明:
- CA如何证明自己?
- CA证书的格式以及标准。
- 证书的弱点。
- 传输过程中CA证书被篡改或者被替换,如何进行加密传输认证。
CA如何证明自己?
CA证书目前比较知名和权威的也就那么几家,DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们之间的区别在于可信程度。证书分为DV、OV、EV 这几种,DV是可信程度最低的,可以说连背后是谁都不知道,EV是最高的,它需要接受最高法院的法律审查,可以证明网站的实际拥有者。
但是CA又要怎么证明自己呢?
CA证书通过信任链证明自己,首先根证书开始,向下逐渐找到信任程度更弱的中间CA机构,通过层信任的方式找到最终的CA证书颁发机构进行验证。
无论如何认证,CA 认证最终总会走 ROOT 根证书,ROOT也可以叫做自签名证书,这个是需要强制相信的, 否则自证明的体系是走不下去的。这种自证体系有点像是如何保证最高法院的权威性一样,CA本身包含机器严格的保护措施。
下面这个图也可以说明,实际上根证书是最重要的,客户端和服务端绝对不能泄露根证书,否则CA的体系和HTTPS都会不攻自破。
浏览器的Security的CA证书中,也可以看到类似结构:最上层Root是根证书,GlobaSync 属于中间证书,最底层是具体服务器的证书。
这个层层信任是咋个信任法?其实也挺简单的,那就是上级持有下一级认证的公钥,先验根证书,然后从根证书拿到下一级证书的公钥,往下找中间证书层层认证。
我们以B站的校验过程为例:
- 首先待验证的网站是 bilibili.com,首先找到上级证书GlobaSIgn RSA SSL CA 2018,再找GlobaSIgn RSA SSL CA 2018它的上级证书 GlobaSign Root CA - R1,这个证书是没有上级的,所以可以认为是根证书。
- 既然GlobaSign Root CA - R1是根证书,那么一般情况下浏览器或者操作系统会内置证书,如果发现内置证书,比如下面就会取出GlobaSign Root CA - R1的公钥,验证GlobaSIgn RSA SSL CA 2018是否可信,如果验证通过,说明GlobaSIgn RSA SSL CA 2018这个中间CA是可以信任的。
- 既然GlobaSIgn RSA SSL CA 2018是可以信任的,那么也同样取出公钥认证bilibili.com是否合规。
可以看到B站的认证体系有不少年头了。
整个CA认证体系最终形成一条信任链条,可以证明网站是合法的了。
从上面的图可以看出,为了验证CA的合法性,会从上级一路向下去验证合法性。另外,如果我们自己捏造自证证书注册到操作系统内(Linux利用OpenSSL命令),用浏览器打开会发现这个证书是不会受到Google浏览器信任的(因为浏览器不承认),并且会提示“此网站不受信任”。