这个问题是一个读者面试时遇到的一个问题,准备过面试的人应该都记得,非对称加密与对称加密的区别之一就是非对称加密的速度慢,但是我们做业务开发的时候通常都是直接调用算法,对其原因并没有过多深究,因此如果有面试官问到了这个问题,的确会让人措手不及。正好借着这篇文章来说一说。
对称加密与非对称加密
首先我们先来说一下到底什么是对称加密,什么是非对称加密,这一节主要是用一些例子来介绍一下对称加密和非对称加密是什么,如果你已经了解了,可以跳过本节。
对称加密
高中生小明和小红是一对“地下情侣”,可偏偏他们一个坐在教室前,一个坐在教室后,所以晚自习的时候也只能通过纸条传情。这时一个很尴尬的事情就出现了,由于无法直接将纸条交给对方,因此纸条必须要经过多个人的传递,可总有一两个八卦的人喜欢看纸条里写的什么。为了避免被班主任抓包以及被同学们窥视,他们两约定,用现代汉语词典当作“密码本”,以后传纸条时,纸条上的内容是要写的字在词典里的页码及顺序,这样即使纸条被别人看了,不知道密码本是什么的人也就不会得知纸条里的真正内容了。
在上述的例子中,纸条是承载信息的载体,纸条里的内容是信息,汉语词典是密钥,将文字映射到汉语词典的页码和顺序是加密方式(算法)。
类似于上面这种,在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥的加密方式就是对称密钥加密(Symmetric-key algorithm),简称对称加密。常见的对称加密算法有:AES、DES、3DES
所以你可以将对称加密简单理解为:一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。他们之间的关系如下图所示(这里借用一下@寒食君的图):
弊端
这种加密方式虽然简单,但是其弊端也是非常明显的。在上面的例子中,如果传递纸条的人知道了他们这种加密方式,那就同样可以通过查阅汉语词典解析出他们的纸条内容。如下图所示。这样为什么众多抗战片中会出现疯狂抢夺密码本这一情节也就很好理解了。
非对称加密
再举一个生活中非常常见的例子。小区里的小伙伴们经常可以在自家的邮箱里收到信件,比如你的录取通知书,当然更多可能是广告。不过,虽然说所有人都可以往里面扔邮件,但是只有你可以打开这个邮箱查看这个邮件。
上面这个过程就是一个很形象的非对称加密。
非对称加密不同于对称加密,它有一对秘钥,一个称为公钥(publicKey) ,另一个称为私钥(privateKey),并且*只知道公钥是无法推算出私钥。*就和上面的例子中只知道邮箱位置却并不能打开邮箱是一个道理。常见的非对称加密算法有:RSA、DSA、ECC
另外,这种算法还有一个特别神奇的功能,那就是通过公钥加密的内容,只有私钥才可以解开,而通过私钥加密的内容,只有公钥才可以解开。
公钥/私钥的用法
第一种用法:公钥加密,私钥解密。---用于加解密
第二种用法:私钥签名,公钥验签。---用于签名
其实很容易理解:
既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;
既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
这里提一点:签名 ≠ 加密,通俗点说加密就是你哪怕看到了不该看到的东西,也理解不了。而签名就是你做了任何事,都抵赖不了。
为什么非对称加密比对称加密慢?
介绍了这两种加密方式后,我们终于可以回到本篇文章的开头了,为什么非对称加密会比对称加密慢?
这是因为对称加密主要的运算是位运算,速度非常快,如果使用硬件计算,速度会更快。以 AES 算法为例,如下图所示,其运算本质上来说就是位移和替换。
但是非对称加密计算一般都比较复杂,比如 RSA,它里面涉及到大数乘法、大数模等等运算。其加解密可以用下面的公式来表示:
我们知道,幂运算的本质是乘法,乘法的基础单位是加法,也就是我们最常见的整数加。学过数字逻辑电路的同学想必都知道,在电路上实现“加法”比异或(XOR)要麻烦的多,况且后面还有一个模运算。因此非对称加密的速度自然而然是比不过对称加密的。
当然,我想另外还有一个原因是,AES 中的许多中间计算过程是可以事先计算好的。加密数据时许多中间过程可以直接查表,而不需要实时地计算。
通常情况下,非对称加密(如 RSA)的解密速度会比加密速度更慢,详情可参考Why is RSA decryption slow?
时空性
这里另外提一点,我们在学习算法的时候,一定听过时间复杂度和空间复杂度这两个名词。鱼和熊掌不可兼得,通常情况下,一个算法如果运行比较快,那么空间消耗相对来说就会高一些,反之亦然。因此才会有拿空间换时间的说法。
从上一节我们可以知道,非对称加密运行起来通常比对称加密慢,那么这时就有一个问题了,对于密钥的存储情况也是这样吗?非对称加密对于密钥的存储会比对称加密的密钥存储少吗?
答案是的确如此,在对称加密中,当信息量大的时候,要求密钥量也要足够大,需要每两个人之间都有一个密钥,也就是对于 n 个人来说,一共需要 n(n-1)/2 个密钥才能确保两两之间对话不被其他人知道。
而在非对称加密中,每个人都有公钥和私钥,对于 n 个人来说,一共要 2n 个密钥,就能保证两两之间对话不被其他人知道。
什么?你问我这个公式怎么来的?数学归纳法了解一下?
这么看,非对称加密虽然效率低下,但是存储成本低且相对安全,这也就解释了为什么非对称加密应用如此广泛了。
HTTPS
既然无法做到既安全又快速的加解密,那我们在实际使用时只能尽量达到一个动态的平衡。
因此我们在项目中通常会采用如下这种将两种加密算法结合在一起的使用方式:
- 首先随机生成单次请求加密密钥(clientAesKey,长度为 16 位,可以用 26 个字母和数字组成)
- RSA 负责加密一个字符串(clientAesKey)、
- AES 负责用这个字符串(clientAesKey)、明文加密为一个密文。
- 解密时首先要用 RSA 获取这个字符串(clientAesKey)、然后再用 AES 解密密文。
之所以本节的标题是 HTTPS,是因为在 HTTPS 中就使用了上述这种加解密的方式。关于 HTTPS 的详解,可以参考我的好朋友寒食君的这篇《谈恋爱也要懂 HTTPS》。
现在如果有面试官问你,在 https 中采用了哪种加密方式,我想你应该知道答案了吧。