个人随笔
目录
当前位置: 首页 HTTP HTTP协议-19:对称加密与非对称加密、数字签名与证书
HTTP协议-19:对称加密与非对称加密、数字签名与证书
2020-03-28 23:53:23

HTTPS的安全性是由TLS来保证的。

你一定很好奇,它是怎么为HTTP增加了机密性、完整性,身份认证和不可否认等特性的呢?

先说说机密性。它是信息安全的基础,缺乏机密性TLS就会成为“无水之源”“无根之木”。

实现机密性最常用的手段是“加密”(encrypt),就是把消息用某种方式转换成谁也看不懂的乱码,只有掌握特殊“钥匙”的人才能再转换出原始文本。

这里的“钥匙”就叫做“密钥”(key),加密前的消息叫“明文”(plain text/clear text),加密后的乱码叫“密文”(cipher text),使用密钥还原明文的过程叫“解密”(decrypt),是加密的反操作,加密解密的操作过程就是“加密算法”。

所有的加密算法都是公开的,任何人都可以去分析研究,而算法使用的“密钥”则必须保密。那么,这个关键的“密钥”又是什么呢?

由于HTTPS、TLS都运行在计算机上,所以“密钥”就是一长串的数字,但约定俗成的度量单位是“位”(bit),而不是“字节”(byte)。比如,说密钥长度是128,就是16字节的二进制串,密钥长度1024,就是128字节的二进制串。

按照密钥的使用方式,加密可以分为两大类:对称加密和非对称加密

1.对称加密

“对称加密”很好理解,就是指加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性。

举个例子,你想要登录某网站,只要事先和它约定好使用一个对称密码,通信过程中传输的全是用密钥加密后的密文,只有你和网站才能解密。黑客即使能够窃听,看到的也只是乱码,因为没有密钥无法解出明文,所以就实现了机密性。

TLS里有非常多的对称加密算法可供选择,比如RC4、DES、3DES、AES、ChaCha20等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有AES和ChaCha20。

AES的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是128、192或256。它是DES算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。

ChaCha20是Google设计的另一种加密算法,密钥长度固定为256位,纯软件运行性能要超过AES,曾经在移动客户端上比较流行,但ARMv8之后也加入了AES硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错算法。

2.加密分组模式

对称算法还有一个“分组模式”的概念,它可以让算法用固定长度的密钥加密任意长度的明文,把小秘密(即密钥)转化为大秘密(即密文)。

最早有ECB、CBC、CFB、OFB等几种分组模式,但都陆续被发现有安全漏洞,所以现在基本都不怎么用了。最新的分组模式被称为AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是GCM、CCM和Poly1305。

把上面这些组合起来,就可以得到TLS密码套件中定义的对称加密算法。

比如,AES128-GCM,意思是密钥长度为128位的AES算法,使用的分组模式是GCM;ChaCha20-Poly1305的意思是ChaCha20算法,使用的分组模式是Poly1305。

你可以用实验环境的URI“/24-1”来测试OpenSSL里的AES128-CBC,在URI后用参数“key”“plain”输入密钥和明文,服务器会在响应报文里输出加密解密的结果。

  1. https://www.chrono.com/24-1?key=123456
  2. algo = aes_128_cbc
  3. plain = hello openssl
  4. enc = 93a024a94083bc39fb2c2b9f5ce27c09
  5. dec = hello openssl

3.非对称加密

对称加密看上去好像完美地实现了机密性,但其中有一个很大的问题:如何把密钥安全地传递给对方,术语叫“密钥交换”。

因为在对称加密算法中只要持有密钥就可以解密。如果你和网站约定的密钥在传递途中被黑客窃取,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了。

这个问题该怎么解决呢?

你或许会说:“把密钥再加密一下发过去就好了”,但传输“加密密钥的密钥”又成了新问题。这就像是“鸡生蛋、蛋生鸡”,可以无限递归下去。只用对称加密算法,是绝对无法解决密钥交换的问题的。

所以,就出现了非对称加密(也叫公钥加密算法)。

它有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,“不对称”,公钥可以公开给任何人使用,而私钥必须严格保密。

公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。

非对称加密可以解决“密钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文。

非对称加密算法的设计要比对称算法难得多,在TLS里只有很少的几种,比如DH、DSA、RSA、ECC等。

RSA可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。

10年前RSA密钥的推荐长度是1024,但随着计算机运算能力的提高,现在1024已经不安全,普遍认为至少要2048位。

ECC(Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法ECDHE用于密钥交换,ECDSA用于数字签名。

目前比较常用的两个曲线是P-256(secp256r1,在OpenSSL称为prime256v1)和x25519。P-256是NIST(美国国家标准技术研究所)和NSA(美国国家安全局)推荐使用的曲线,而x25519被认为是最安全、最快速的曲线。

ECC名字里的“椭圆”经常会引起误解,其实它的曲线并不是椭圆形,只是因为方程很类似计算椭圆周长的公式,实际的形状更像抛物线,比如下面的图就展示了两个简单的椭圆曲线。

两个简单的椭圆曲线:y2=x3+7,y2=x3-x

比起RSA,ECC在安全强度和性能上都有明显的优势。160位的ECC相当于1024位的RSA,而224位的ECC则相当于2048位的RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。

实验环境的URI“/24-2”演示了RSA1024,你在课后可以动手试一下。

4.混合加密

看到这里,你是不是认为可以抛弃对称加密,只用非对称加密来实现机密性呢?

很遗憾,虽然非对称加密没有“密钥交换”的问题,但因为它们都是基于复杂的数学难题,运算速度很慢,即使是ECC也要比AES差上好几个数量级。如果仅用非对称加密,虽然保证了安全,但通信速度有如乌龟、蜗牛,实用性就变成了零。

实验环境的URI“/24-3”对比了AES和RSA这两种算法的性能,下面列出了一次测试的结果:

  1. aes_128_cbc enc/dec 1000 times : 0.97ms, 13.11MB/s
  2. rsa_1024 enc/dec 1000 times : 138.59ms, 93.80KB/s
  3. rsa_1024/aes ratio = 143.17
  4. rsa_2048 enc/dec 1000 times : 840.35ms, 15.47KB/s
  5. rsa_2048/aes ratio = 868.13

可以看到,RSA的运算速度是非常慢的,2048位的加解密大约是15KB/S(微秒或毫秒级),而AES128则是13MB/S(纳秒级),差了几百倍。

那么,是不是能够把对称加密和非对称加密结合起来呢,两者互相取长补短,即能高效地加密解密,又能安全地密钥交换。

这就是现在TLS里使用的混合加密方式,其实说穿了也很简单:

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

然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有16字节或32字节,所以慢一点也无所谓。

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

这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性。

不过这只是“万里长征的第一步”,后面还有完整性、身份认证、不可否认等特性没有实现,所以现在的通信还不是绝对安全。

小结

  • 1)加密算法的核心思想是“把一个小秘密(密钥)转化为一个大秘密(密文消息)”,守住了小秘密,也就守住了大秘密;
  • 2)对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换,常用的有AES和ChaCha20;
  • 3)非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢,常用的有RSA和ECC;
  • 4)把对称加密和非对称加密结合起来就得到了“又好又快”的混合加密,也就是TLS里使用的加密方式。

但仅有机密性,离安全还差的很远。

黑客虽然拿不到会话密钥,无法破解密文,但可以通过窃听收集到足够多的密文,再尝试着修改、重组后发给网站。因为没有完整性保证,服务器只能“照单全收”,然后他就可以通过服务器的响应获取进一步的线索,最终就会破解出明文。

另外,黑客也可以伪造身份发布公钥。如果你拿到了假的公钥,混合加密就完全失效了。你以为自己是在和“某宝”通信,实际上网线的另一端却是黑客,银行卡号、密码等敏感信息就在“安全”的通信过程中被窃取了。

所以,在机密性的基础上还必须加上完整性、身份认证等特性,才能实现真正的安全。

5.摘要算法

实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。

你可以把摘要算法近似地理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。

换一个角度,也可以把摘要算法理解成特殊的“单向”加密算法,它只有算法,没有密钥,加密后的数据无法解密,不能从摘要逆推出原文。

摘要算法实际上是把数据从一个“大空间”映射到了“小空间”,所以就存在“冲突”(collision,也叫碰撞)的可能性,就如同现实中的指纹一样,可能会有两份不同的原文对应相同的摘要。好的摘要算法必须能够“抵抗冲突”,让这种可能性尽量地小。

因为摘要算法对输入具有“单向性”和“雪崩效应”,输入的微小不同会导致输出的剧烈变化,所以也被TLS用来生成伪随机数(PRF,pseudo random function)。

你一定在日常工作中听过、或者用过MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成16字节和20字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在TLS里已经被禁止使用了。

目前TLS推荐使用的是SHA-1的后继者:SHA-2。

SHA-2实际上是一系列摘要算法的统称,总共有6种,常用的有SHA224、SHA256、SHA384,分别能够生成28字节、32字节、48字节的摘要。

你可以用实验环境的URI“/25-1”来测试一下TLS里的各种摘要算法,包括MD5、SHA-1和SHA-2。

  1. https://www.chrono.com/25-1?algo=md5
  2. https://www.chrono.com/25-1?algo=sha1
  3. https://www.chrono.com/25-1?algo=sha256

6.完整性

摘要算法保证了“数字摘要”和原文是完全等价的。所以,我们只要在原文后附上它的摘要,就能够保证数据的完整性。

比如,你发了条消息:“转账1000元”,然后再加上一个SHA-2的摘要。网站收到后也计算一下消息的摘要,把这两份“指纹”做个对比,如果一致,就说明消息是完整可信的,没有被修改。

如果黑客在中间哪怕改动了一个标点符号,摘要也会完全不同,网站计算比对就会发现消息被窜改,是不可信的。

不过摘要算法不具有机密性,如果明文传输,那么黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。

所以,真正的完整性必须要建立在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客无法得知明文,也就没有办法动手脚了。

这有个术语,叫哈希消息认证码(HMAC)。

7.数字签名

加密算法结合摘要算法,我们的通信过程可以说是比较安全了。但这里还有漏洞,就是通信的两个端点(endpoint)。

就像一开始所说的,黑客可以伪装成网站来窃取信息。而反过来,他也可以伪装成你,向网站发送支付、转账等消息,网站没有办法确认你的身份,钱可能就这么被偷走了。

现实生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,就能够证明这份文件确实是由本人而不是其他人发出的。

你回想一下之前的课程,在TLS里有什么东西和现实中的签名、印章很像,只能由本人持有,而其他任何人都不会有呢?只要用这个东西,就能够在数字世界里证明你的身份。

没错,这个东西就是非对称加密里的“私钥”,使用私钥再加上摘要算法,就能够实现“数字签名”,同时实现“身份认证”和“不可否认”。

数字签名的原理其实很简单,就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密。

但又因为非对称加密效率太低,所以私钥只加密原文的摘要,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输。

签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的。

刚才的这两个行为也有专用术语,叫做“签名”和“验签”。

只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

比如,你用自己的私钥签名一个消息“我是小明”。网站收到后用你的公钥验签,确认身份没问题,于是也用它的私钥签名消息“我是某宝”。你收到后再用它的公钥验一下,也没问题,这样你和网站就都知道对方不是假冒的,后面就可以用混合加密进行安全通信了。

实验环境的URI“/25-2”演示了TLS里的数字签名,它使用的是RSA1024。

8.数字证书和CA

到现在,综合使用对称加密、非对称加密和摘要算法,我们已经实现了安全的四大特性,是不是已经完美了呢?

不是的,这里还有一个“公钥的信任”问题。因为谁都可以发布公钥,我们还缺少防止黑客伪造公钥的手段,也就是说,怎么来判断这个公钥就是你或者某宝的公钥呢?

真是“按下葫芦又起了瓢”,安全还真是个麻烦事啊,“一环套一环”的。

我们可以用类似密钥交换的方法来解决公钥认证问题,用别的私钥来给公钥签名,显然,这又会陷入“无穷递归”。

但这次实在是“没招”了,要终结这个“死循环”,就必须引入“外力”,找一个公认的可信第三方,让它作为“信任的起点,递归的终点”,构建起公钥的信任链。

这个“第三方”就是我们常说的CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。

CA对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)。

知名的CA全世界就那么几家,比如DigiCert、VeriSign、Entrust、Let’s Encrypt等,它们签发的证书分DV、OV、EV三种,区别在于可信程度。

DV是最低的,只是域名级别的可信,背后是谁不知道。EV是最高的,经过了法律和审计的严格核查,可以证明网站拥有者的身份(在浏览器地址栏会显示出公司的名字,例如Apple、GitHub的网站)。

不过,CA怎么证明自己呢?

这还是信任链的问题。小一点的CA可以让大CA签名认证,但链条的最后,也就是Root CA,就只能自己证明自己了,这个就叫“自签名证书”(Self-Signed Certificate)或者“根证书”(Root Certificate)。你必须相信,否则整个证书信任链就走不下去了。

有了这个证书体系,操作系统和浏览器都内置了各大CA的根证书,上网的时候只要服务器发过来它的证书,就可以验证证书里的签名,顺着证书链(Certificate Chain)一层层地验证,直到找到根证书,就能够确定证书是可信的,从而里面的公钥也是可信的。

我们的实验环境里使用的证书是“野路子”的自签名证书(在Linux上用OpenSSL命令行签发),肯定是不会被浏览器所信任的,所以用Chrome访问时就会显示成红色,标记为不安全。但你只要把它安装进系统的根证书存储区里,让它作为信任链的根,就不会再有危险警告。

9.证书体系的弱点

证书体系(PKI,Public Key Infrastructure)虽然是目前整个网络世界的安全基础设施,但绝对的安全是不存在的,它也有弱点,还是关键的“信任”二字。

如果CA失误或者被欺骗,签发了错误的证书,虽然证书是真的,可它代表的网站却是假的。

还有一种更危险的情况,CA被黑客攻陷,或者CA有恶意,因为它(即根证书)是信任的源头,整个信任链里的所有证书也就都不可信了。

这两种事情并不是“耸人听闻”,都曾经实际出现过。所以,需要再给证书体系打上一些补丁。

针对第一种,开发出了CRL(证书吊销列表,Certificate revocation list)和OCSP(在线证书状态协议,Online Certificate Status Protocol),及时废止有问题的证书。

对于第二种,因为涉及的证书太多,就只能操作系统或者浏览器从根上“下狠手”了,撤销对CA的信任,列入“黑名单”,这样它颁发的所有证书就都会被认为是不安全的。

小结

  • 1)摘要算法用来实现完整性,能够为数据生成独一无二的“指纹”,常用的算法是SHA-2;
  • 2)数字签名是私钥对摘要的加密,可以由公钥解密后验证,实现身份认证和不可否认;
  • 3)公钥的分发需要使用数字证书,必须由CA的信任链来验证,否则就是不可信的;
  • 4)作为信任链的源头CA有时也会不可信,解决办法有CRL、OCSP,还有终止信任。

相关加密签名算法可参考博文:
常见加密算法及常见加密算法原理
三、数字签名与数字加密

作者:王侦
链接: https://www.jianshu.com/p/9e46908750de
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 843
上一篇: 用Java模拟一个Gossip协议的简单例子
下一篇: HTTP协议-18:HTTPS

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2

玻璃钢生产厂家广东玻璃钢医疗外壳价格长治玻璃钢家具厂家山南玻璃钢花盆制作韶关玻璃钢动物雕塑加工定西玻璃钢花箱加工盘锦玻璃钢摆件厂家遵义玻璃钢茶几哪家好北海玻璃钢座椅公司廊坊玻璃钢家具定做黑河玻璃钢树池厂家直销赤峰玻璃钢外壳多少钱金昌玻璃钢休闲椅公司烟台玻璃钢沙发价格贵港玻璃钢卡通雕塑江西玻璃钢机械外壳厂家直销亳州商业美陈绵阳玻璃钢前台定制海东玻璃钢动物雕塑制造安庆玻璃钢造型多少钱通化玻璃钢摆件哪家好榆林玻璃钢休闲椅上海玻璃钢雕塑公司兰州玻璃钢座椅批发蚌埠玻璃钢造型定制成都玻璃钢装饰多少钱云南玻璃钢花瓶制造温州玻璃钢沙发定制江西玻璃钢造型厂家东莞玻璃钢人物雕塑生产厂家莱芜玻璃钢医疗外壳厂家直销香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化