加密技术科普

我们来自字节跳动飞书商业应用研发部(Lark Business Applications),目前我们在北京、深圳、上海、武汉、杭州、成都、广州、三亚都设立了办公区域。我们关注的产品领域主要在企业经验管理软件上,包括飞书 OKR、飞书绩效、飞书招聘、飞书人事等 HCM 领域系统,也包括飞书审批、OA、法务、财务、采购、差旅与报销等系统。欢迎各位加入我们。

本文作者:飞书商业应用研发部 朱忠华

欢迎大家关注飞书技术,每周定期更新飞书技术团队技术干货内容,想看什么内容,欢迎大家评论区留言~

一、浅谈密码技术

密码这个词有很多种的解释,在现代社会如果不接触编程的话,那么普遍的认为是我们设置的登录密码、或者是去银行取钱时输入的数字。都是我们在注册时实现给提供服务的一方存储一组数字,以后我们登录的时候就用这组数字相当于就证明了我们的身份。这个数字通常来说就是叫做密码。

而我们需要了解的不是上面说的密码,而是一种“密码术”,就是对于要传递的信息按照某种规则进行转换,从而隐藏信息的内容。这种方法可以使机密信息得以在公开的渠道传递而不泄密。使用这种方法,要经过加密过程。在加密过程中我们需要知道下面的这些概念:

  • 原文:或者叫明文,就是被隐藏的文字。
  • 加密法:指隐藏原文的法则。
  • 密文:或者叫伪文,指对原文按照加密法处理过后生成的可公开传递的文字。
  • 密钥:在加密法中起决定性的因素,可能是数字、词汇,也可能是一些字母,或者这些东西的组合。

加密的结果生成了密文,要想让接受者能够读懂这些密文,那么就要把加密法以及密钥告诉接受者,否则接受者无法对密文解密,也就无法读懂原文。

从历史的角度来看,密码学大概可以分为古典密码学和近现代密码学两个阶段。两者以现代信息技术的诞生为分界点,现在所讨论的密码学多指的是后者,建立在信息论和数学成果基础之上的。

1.1 古典密码学

古典密码学源自于数千年前,最早在公元前 1900 年左右的古埃及,就出现了通过使用特殊字符和简单替换式密码来保护信息。美索不达米亚平原上曾经出土一个公元前 1500 年左右的泥板,其上记录了加密描述的陶瓷器上釉的工艺配方。古希腊时期(公元前 800 ﹣前 146 年)还发明了通过物理手段来隐藏信息的“隐写术”,例如使用牛奶书写、用蜡覆盖文字等。后来在古罗马时期还出现了基于替换加密的凯撒密码,据称凯撒曾用此方法与其部下通信而得以命名。这些手段多数是采用简单的机械工具来保护秘密,在今天看来毫无疑问是十分简陋,很容易猜出来的。严格来看,可能都很难称为密码科学。

凯撒密码是当偏移量是 3 的时候,所有的字母都 A 都将被替换成 D,B 变成 E,以此类推。

1.2 近代密码学

近代密码学的研究来自于第一、二次世界大战中对于军事通信进行保护和猜出来的需求。1901 年 12月,意大利的工程师 Guglielmo Marconi(奎里亚摩•马可尼)成功完成了跨越大西洋的无线电通信的实验,在全球范围内引发轰动,推动了无线电通信时代的到来。无线电大大提高了远程通信的能力,但是它有一个天然的缺陷——很难限制接收方,这就意味着你所传的信息有可能被拦截,因此就催生了加密技术的发展。

对于无线电信息进行加密和解密也直接促进了近现代密码学和计算机技术的出现。反过来这些科技进步也影响了时代的发展。一战时期德国外交部长 Arthur Zimmermann(阿瑟•齐默尔曼)拉拢墨西哥构成抗美军事同盟的电报(1917 年 1 月 16 日)被英国情报机构— 40 号办公室破译,直接导致了美国的参战;二战时期德国使用的恩尼格玛(Enigma)密码机(当时最先进的加密设备)被盟军成功破译(1939 年到 1941 年),导致大西洋战役德国失败。据称,二战时期光英国从事密码学研究的人员就达到 7000 人,而他们的成果使二战结束的时间至少提前了一到两年时间。

接下来就是可以称之为是密码学发展史上里程碑的事件了。1945 年 9月 1 日,Claude Elwood Shannon(克劳德•艾尔伍德•香农)完成了划时代的内部报告《A Mathematical Theory of Cryptography(密码术的一个数学理论)》,1949 年 10 月,该报告以《Communication Theory of Secrecy Systems(保密系统的通信理论)》为题在 Bell System Technical Journal(贝尔系统技术期刊)上正式发表。这篇论文首次将密码学和信息论联系到一起,为对称密码技术提供了数学基础。这也标志着近现代密码学的正式建立。这也是密码学发展史上的第一座里程碑性事件。

密码学发展史上的第二个里程碑性事件是 DES 的出现。DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的分组密码算法,1977 年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

密码学发展史上的第三个里程碑性事件就是我们区块链中广泛应用的公钥密码,也就是非对称密码算法的出现。1976年11月,Whitfield Diffie 和 Martin E.Hellman 在 IEEE Transactions on Information Theory 上发表了论文《New Directions in Cryptography(密码学的新方向)》,探讨了无需传输密钥的保密通信和签名认证体系问题,正式开创了现代公钥密码学体系的研究。在公钥密码发现以前,如果需要保密通信,通信双方事先要对加解密的算法以及要使用的密钥进行事先协商,包括送鸡毛信,实际上是在传送密钥。但自从有了公钥密码,需要进行秘密通信的双方不再需要进行事前的密钥协商了。公钥密码在理论上是不保密的,在实际上是保密的。也就是说,公钥密码是可以猜出来的,但需要极长的时间,等到猜出来了,这个秘密也没有保密的必要了。

密码学最基础的分支有三个,第一个是单向 散列函数,第二个是对称密码技术,第三个是非对称密码技术。那么接下来我们就以介绍这 3 个概念为主线引出开题中我们提到的概念。

二、摘要算法

2.1 概念

数据摘要算法(Digest Algorithm)是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名、数据完整性校验等功能,由于其不可逆性,有时候会被用作敏感信息的加密。数据摘要算法也被称为哈希(Hash)算法或散列算法,在实现上是一个单向的散列函数。

无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。一般地,只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出。只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息(不可逆性)。

大量的应用都在使用 MD5 或者 SHA 算法计算一个唯一的 id。比如 Git 中的提交记录、文件的完整性校验、各种语言中字典或者 Map 的实现等等。很多场景下,我们使用散列算法并不是为了满足什么加密需求,而是利用它可以对任意长度的输入,计算出一个定长的 id。

作为密码学的算法,散列算法除了提供唯一的 id,其更大的利用价值还在于它的不可逆性。当用户注册,提交账号密码时,作为一个安全的应用,是绝对不能够存储明文密码的。因此,我们对用户的密码通过散列算法进行计算,存储最终的散列值。在后续登录的过程中,我们如果计算出的用户提交的密码的散列值和你存储的散列值一致,就可以通过验证了。这样一来,任何人(即使是内部员工)都不知道用户真实的密码是什么,而用户也能够完成密码的校验。

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

2.2 什么是单向散列函数?

首先,我们从名字上看,一眼就能看出来单向散列函数有两个关键修饰词,“单向”和“散列”。其实,在数学上,单向函数和散列函数是两个不同类型的函数。所以,我们要想理解单向散列函数,我们就要先知道什么是单向函数,什么又是散列函数。

单向函数(One-way Function)是正向计算容易,逆向运算困难的函数。也就是说,给定你一个输入,你很容易计算出输出;但是给定你一个输出,你却很难计算出输入是什么。

一个更实用的单向函数,正向计算会更容易,容易程度就是这个函数的计算性能;一个更实用的单向函数,逆向运算会更困难,困难程度就是这个函数的破解强度。一个实用的单向函数,计算强度和破解强度要均衡考量,不可偏废。

散列函数(Hash Function) 是一个可以把任意大小的数据,转行成固定长度的数据的函数。比如说,无论输入数据是一个字节,或者一万个字节,输出数据都是 16 个字节。我们把转换后的数据,叫做散列值。因为散列函数经常被人们直译为哈希函数,所以我们也可以称散列值为哈希值。通常的,对于给定的输入数据和散列函数,散列值是确定不变的。

会不会存在散列值相同的两个或者多个数据呢?——是确定存在的。通常,我们把这种情况称为散列值碰撞。对于散列函数,散列值碰撞可不是一件好事情。

最直观的办法,就是在输出数据的长度上想办法。虽然散列值长度固定,但是,我们可以让数据变得更长,散列值越长,存在相同散列值的概率就越小,发生碰撞的可能性就越小。但从另一个角度来说,散列值越长,通常也就意味着计算越困难,计算性能越差。散列值的长度选择,应该是权衡性能后的结果。

除了散列值长度之外,想要降低散列值碰撞的可能性,我们还要考虑散列值的质量。一个好的散列函数,它的散列值应该是均匀分布的。也就是说,每一个散列值出现的概率都是一样的。如果不这样的话,一部分散列值出现的概率就会较高,另一部分散列值出现的概率会较低,别人就更容易构造出两个或者多个数据,使得它们具有相同的散列值。这种行为,叫做碰撞攻击。

雪崩效应(Avalanche Effect) 是密码学算法一个常见的特点,指的是输入数据的微小变换,就会导致输出数据的巨大变化。严格雪崩效应是雪崩效应的一个形式化指标,我们也常用来衡量均匀分布。严格雪崩效应指的是,如果输入数据的一位反转,输出数据的每一位都有 50% 的概率会发生变化。

一个适用于密码学的单向散列函数,就要具有雪崩效应的特点,也就是说,如果一个单向散列函数具有雪崩效应,那么对于给定的数据,构造出一个新的、具有相同散列值的数据是困难的。

2.3 有哪些具体的消息摘要算法?

  • CRC8、CRC16、CRC32:CRC(Cyclic Redundancy Check,循环冗余校验)算法出现时间较长,应用也十分广泛,尤其是通讯领域。现在应用最多的就是 CRC32 算法,它产生一个 4 字节(32位)的校验值,一般是以 8 位十六进制数,如FA 12 CD 45等。CRC 算法的优点在于简便、速度快。严格的来说,CRC 更应该被称为数据校验算法,但其功能与数据摘要算法类似,因此也作为测试的可选算法。
  • MD2 、MD4、MD5:这是应用非常广泛的一个算法家族,尤其是 MD5(Message-Digest Algorithm 5,消息摘要算法版本5),它由 MD2、MD3、MD4 发展而来,由 Ron Rivest(RSA公司)在 1992 年提出,目前被广泛应用于数据完整性校验、数据(消息)摘要、数据加密等。MD2、MD4、MD5 都产生 16 字节(128位)的校验值,一般用32位十六进制数表示。MD2的算法较慢但相对安全,MD4 速度很快,但安全性下降,MD5 比 MD4 更安全、速度更快。如果不是长度受限(32 个字符),我还是不推荐你继续使用 MD5 的。
  • SHA1、SHA256、SHA384、SHA512:SHA(Secure Hash Algorithm)是由美国专门制定密码算法的标准机构——美国国家标准技术研究院(NIST)制定的,SHA系列算法的摘要长度分别为:SHA 为 20 字节(160位)、SHA256 为 32 字节(256位)、 SHA384 为 48 字节(384位)、SHA512 为 64 字节(512位),由于它产生的数据摘要的长度更长,因此更难以发生碰撞,因此也更为安全,它是未来数据摘要算法的发展方向。由于 SHA 系列算法的数据摘要长度较长,因此其运算速度与 MD5 相比,也相对较慢。和 MD5 相同,虽然 SHA 的唯一性也被破解了,但是这也不会构成大的安全问题。目前,SHA-256 普遍被认为是相对安全的散列算法,也是我最推荐你使用的散列算法
  • RIPEMD、PANAMA、TIGER、ADLER32 等:RIPEMD 是 Hans Dobbertin 等 3 人在对 MD4、MD5 缺陷分析基础上,于 1996 年提出来的,有 4 个标准 128、160、256 和 320,其对应输出长度分别为 16 字节、20 字节、32 字节和 40 字节。TIGER 由 Ross 在 1995 年提出。Tiger 号称是最快的 Hash 算法,专门为 64 位机器做了优化。
  • 国密 SM3。国密算法 SM3 是一种散列算法。其属于国家标准,算法公开,加密强度和国际标准的 SHA-256 相当。

另外,我们在使用散列算法的时候,有一点需要注意一下,一定要注意加“盐”。所谓“盐”,就是一串随机的字符,是可以公开的。将用户的密码“盐”进行拼接后,再进行散列计算,这样,即使两个用户设置了相同的密码,也会拥有不同的散列值。同时,黑客往往会提前计算一个彩虹表来提升暴力破解散列值的效率,而我们能够通过加“盐”进行对抗。“盐”值越长,安全性就越高。

总的来说,在使用的时候,你要记住下面这些内容:对称加密具备较高的安全性和性能,要优先考虑。在一对多的场景中(如多人登录服务器),存在密钥分发难题的时候,我们要使用非对称加密;不需要可逆计算的时候(如存储密码),我们就使用散列算法。在具体算法的选取上,你只需要记住:对称加密用 AES-CTR、非对称加密用 ECC、散列算法用 SHA256 加盐。这些算法就能够满足大部分的使用场景了,并且在未来很长一段时间内,都可以保持一个较高的安全强度。

2.4 HMAC

使用消息验证码的前提,就是信息的发送方和接收方要持有相同的密钥,这和我们前面讨论的对称密钥的条件是一样的。能够使用对称密钥的场景,都能够满足这个前提。

另外,信息的发送方和接收方要使用相同的消息验证函数。这个函数的输入数据就是对称密钥和待验证信息。信息的发送方使用消息验证函数,可以生成消息验证码。然后,信息接收方对比接收到的消息验证码和自己生成的消息验证码。如果两个消息验证码是一样的,就表明待验证信息不是伪造的信息。否则,待验证信息就是被篡改过的信息。

HMAC,全称:基于单向散列函数的消息验证码(Hash-based Message Authentication Code)。在 HMAC 的算法里,单向散列函数的输入数据是由对称密钥和待验证消息构造出来的。

到这里,你是不是早就有了一个疑问,消息验证函数为什么还需要对称密钥呢? 我们前面提到,单向散列函数也可以验证数据的完整性。为什么它不直接使用单向散列函数呢?

我们先来看看,如果没有对称密钥的加入,消息验证码还能不能工作。信息发送方把待验证信息和消息验证码都发送给信息接收方。假设存在一个中间攻击者,能够解开待验证信息和消息验证码。由于单向散列函数是公开的算法,中间攻击者就可以篡改待验证信息,重新生成消息验证码。

然后,中间攻击者把篡改的信息和篡改的验证码发给信息接收方。篡改的信息和篡改的验证码能够通过信息接收方的信息验证。也就是说,这样的话,信息接收方就没有办法识别出这个信息是不是原始的、没有篡改的信息。这样,信息验证就失效了。

可是,如果对称密钥参与了消息验证码的运算,由于中间攻击者并不知道对称密钥的数据,攻击者就很难伪造出一个能够通过验证的消息验证码。换一个说法,对称密钥的参与,是为了确保散列值来源于原始数据,而不是篡改的数据。

HMAC 算法是由单向散列函数的算法确定的。下面的表格,我列出了一些常见的算法。同样的,我们把 HMAC 算法也按照退役的、遗留的以及现行的算法来分类。

其中,HmacSHA256 和 HmacSHA384 是目前最流行的两个 HMAC 算法。

三、对称加密

对称加密(Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥加密的主要缺点之一。常见的对称加密算法有:DES、3DES(TripleDES)、IDEA、AES、ChaCha20、 RC2、RC4、RC5、Blowfish和国密 SM1 和 SM4等。

DES (数据加密标准,Data Encryption Standard)加密算法是一种分组密码,以 64 位为分组对数据加密,它的密钥长度是 56 位(密钥表面上是 64 位的,然而只有其中的 56 位被实际应用于算法,其余 8 位可以用于奇偶校验。因此,DES 的有效密钥长度仅为 56 位。),加密解密用同一算法。DES 加密算法是对密钥进行保密,而公开算法,包括加密和解密算法。这样,只有掌握了和发送方相同密钥的人才能解读由 DES 加密算法加密的密文数据。因此,破译 DES 加密算法实际上就是搜索密钥的编码。对于 56 位长度的密钥来说,如果用穷举法来进行搜索的话,其运算次数为 2 的 56 次方。

DES算法的入口参数有三个:Key、Data、Mode。其中 Key 为 8 个字节共 64 位,是 DES 算法的工作密钥;Data 也为 8 个字节 64 位,是要被加密或被解密的数据;Mode 为 DES 的工作方式,有两种:加密或解密。

对应的还有 3DES,3DES(或称为 Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的统称。它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

DES 实际上是一个过时的密码学算法,目前已经不推荐使用了。关于 DES,还有一点特别有意思。DES 包含一个关键模块:S 盒,其设计的原理一直没有公开。因此,很多人都相信,这个 S 盒中存在后门,只要美国政府需要,就能够解密任何 DES 密文。

IDEA (国际数据加密算法,International Data Encryption Algorithm)由瑞士研究人员设计,密钥长度为 128 位。对比于其他的密码学算法,IDEA 的优势在于没有专利的限制。相比于 DES 和 AES 的使用受到美国政府的控制,IDEA 的设计人员并没有对其设置太多的限制,这让 IDEA 在全世界范围内得到了广泛地使用和研究。

AES (高级加密标准,Advanced Encryption Standard)加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为 128、192、256,分组长度 128 位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,AES 标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。

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

国密 SM1(SM1 Cryptographic Algorithm)和 SM4(SM4 Cryptographic Algorithm)。我们知道,密码学作为安全的基础学科,如果全部依靠国外的技术,对于国家安全可能产生不利影响。因此,中国政府提出了一系列加密算法。其中,国密算法 SM1 和 SM4 都属于对称加密的范畴。SM1 算法不公开,属于国家机密,只能通过相关安全产品进行使用。而 SM4 属于国家标准,算法公开,可自行实现使用。国密算法的优点显而易见:受到国家的支持和认可。

3.1 加密分组模式

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

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

一般地,我们可以把带关联数据的认证加密看做一个加密模式,就像 CBC 模式一样,我们可以和前面提到的 AES 等加密算法进行组合。但 ChaCha20 和 Poly1305 通常组合在一起;Camellia 与 AES 通常和 GCM 以及 CCM 组合在一起。由于 AEAD 模式相对较新,而 3DES/DES 等遗留或者退役算法又存在明显的安全缺陷,所以,我们一般不会使用遗留或者退役算法的 AEAD 模式。如果我们重新整理一下,综合考虑加密算法和加密模式,那么,当前推荐使用的、有广泛支持的、风险最小的算法是:AES/GCM;ChaCha20/Poly1305;AES/CCM

3.2 小节

在加密通信中(如 HTTPS、VPN、SSH 等),通信双方会协商出一个加密算法和密钥,对传输的数据进行加密,从而防止第三方窃取。在类似数据库加密这种存储加密技术中,通信双方也是将存储空间中的数据进行加密,这样即使硬盘被物理窃取,也不会导致信息丢失。在公司内部,为了避免用户的 Cookie 和隐私信息发生泄漏,也需要对它们进行加密存储。

对于大部分公司来说,选取 AES128 进行加解密运算,就能获得较高的安全性和性能。如果是金融或政府行业,在涉及国家层面的对抗上,有一定的合规需求,则需要应用国密算法。

对称加密的优点是算法公开、计算量小、加密速度快、加密效率高。缺点就是密钥的管理和分发是非常困难的,不够安全。在数据传送前,发送方和接收方必须商定好秘钥,然后双方都必须要保存好秘钥,如果一方的密钥被泄露了,那么加密的信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的唯一秘钥,这会使得收、发双方所拥有的的钥匙数量巨大,秘钥管理也会成为双方的负担。

四、非对称加密

非对称加密(asymmetric cryptography) 也称为公开密钥加密(英语:public-key cryptography,又译为公开密钥加密)。它有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,“不对称”,公钥可以公开给任何人使用,而私钥必须严格保密。

具体的加解密过程就是,发送方使用公钥对信息进行加密,接收方收到密文后,使用私钥进行解密。具体我也画了一张图,你可以和上面的对称加密算法的图一起对照着看一下。可以看到,非对称加密和对称加密算法的最大区别就是,加密和解密使用的密钥是不同的。

对称加密看上去好像完美地实现了机密性,但其中有一个很大的问题:如何把密钥安全地传递给对方,术语叫“密钥交换”。因为在对称加密算法中只要持有密钥就可以解密。如果你和网站约定的密钥在传递途中被黑客窃取,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了。

公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。非对称加密可以解决“密钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文。

非对称加密算法一般有 DH、DSA、RSA、ECC、SM2等

RSA 可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。10 年前 RSA 密钥的推荐长度是 1024,但随着计算机运算能力的提高,现在 1024 已经不安全,普遍认为至少要 2048 位。RSA 的数学难题是:两个大质数 p、q 相乘的结果 n 很容易计算,但是根据 n 去做质因数分解得到 p、q,则需要很大的计算量。RSA 是比较经典的非对称加密算法,它的主要优势就是性能比较快,但想获得较高的加密强度,需要使用很长的密钥。

ECC (椭圆加密算法,Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。目前学术界普遍认为,椭圆曲线的难度高于大质数难题,160 位密钥的 ECC 加密强度,相当于 1088 位密钥的 RSA。因此,ECC 是目前国际上加密强度最高的非对称加密算法。

国密 SM2(SM2 Cryptographic Algorithm)。国密算法 SM2 也是基于椭圆曲线问题设计的,属于国家标准,算法公开,加密强度和国际标准的 ECC 相当。而国密的优势在于国家的支持和认可。

对比于对称加密算法,非对称加密算法最大的优势就是解决密钥分发的问题。因此,现在大部分的认证和签名场景,其实使用的都是非对称加密算法。比如,在 SSH 登录、Git 上传等场景中,我们都可以将自己的公钥上传到服务端,然后由客户端保存私钥。

五、混合加密

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

一组测试数据:RSA 的运算速度是非常慢的,2048 位的加解密大约是 15KB/S(微秒或毫秒级),而 AES128 则是 13MB/S(纳秒级),差了几百倍。

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

这就是混合加密方式,其实说穿了也很简单:在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题。然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。

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

六、数字签名

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

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

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

刚才的这两个行为也有专用术语,叫做“签名(加签)”和“验签”。只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

七、数字证书和 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)一层层地验证,直到找到根证书,就能够确定证书是可信的,从而里面的公钥也是可信的。

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

如果 CA 失误或者被欺骗,签发了错误的证书,虽然证书是真的,可它代表的网站却是假的。还有一种更危险的情况,CA 被黑客攻陷,或者 CA 有恶意,因为它(即根证书)是信任的源头,整个信任链里的所有证书也就都不可信了。这两种事情并不是“耸人听闻”,都曾经实际出现过。所以,需要再给证书体系打上一些补丁。

针对第一种,开发出了 CRL(证书吊销列表,Certificate revocation list)和 OCSP(在线证书状态协议,Online Certificate Status Protocol),及时废止有问题的证书。对于第二种,因为涉及的证书太多,就只能操作系统或者浏览器从根上“下狠手”了,撤销对 CA 的信任,列入“黑名单”,这样它颁发的所有证书就都会被认为是不安全的。

八、总结

加密算法的核心思想是“把一个小秘密(密钥)转化为一个大秘密(密文消息)”,守住了小秘密,也就守住了大秘密;

对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换,常用的有 AES 和 ChaCha20;

非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢,常用的有 RSA 和 ECC;

把对称加密和非对称加密结合起来就得到了“又好又快”的混合加密,也就是 TLS 里使用的加密方式;

摘要算法用来实现完整性,能够为数据生成独一无二的“指纹”,常用的算法是 SHA-2;

数字签名是私钥对摘要的加密,可以由公钥解密后验证,实现身份认证和不可否认;

公钥的分发需要使用数字证书,必须由 CA 的信任链来验证,否则就是不可信的;

作为信任链的源头 CA 有时也会不可信,解决办法有 CRL、OCSP,还有终止信任。

References

  1. 关于加解密、加签验签那些事
  2. 对称加密算法
  3. 极客时间-安全攻防技能30讲
  4. 极客时间-透视HTTP协议

加入我们

扫码发现职位&投递简历

官网投递:job.toutiao.com/s/FyL7DRg

猜你喜欢

转载自juejin.im/post/7166925768012857374
今日推荐