加密相关

凡是涉及到加密的时候,就涉及到安全,但是,在实际的开发过程中,涉及到安全部分的又比较少,有些甚至是框架给你做好了,不需要自己考虑。但是我们也还是需要去熟悉一下的。加密涉及到的东西不算难,有点杂,有些乱,每个人都会讲一点,但是真的去说的时候又讲不出个所以然。所以导致很多人对加密有些误解。所以希望这篇文章对你有所帮助。

先说一下加密的概念吧,因为有些东西确实不是加密,又被大家冠以加密的头衔,久而久之加密与非加密就特别容易混淆了。那加密的概念是什么呢?

密码学中,加密(英语:Encryption)是将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。——维基百科

Base64

首先说一下 Base64 ,网上有人说,Base64 是加密,有人说不是。那他到底是不是呢?想回答这个问题,不难,了解一下 Base64 就行。

Base64 是一种使用 64 个字符来表示二进制数据的一种编码方式。主要作用是将二进制数据重新编码使其成为文本,便于传输。什么意思?举个例子。

比如需要开发一个上传图片的功能,但是我们没有一个用于独立的上传图片的接口,怎么办呢?网页或客户端将图片使用 Base64 转一下,让它成为字符串数据,然后发送字符串即可。

下表为 Base64 码表,图片来自维基百科。

Base64码表

当然,非二进制数据即文本数据也是可以转换的,但是本来就是文本数据(字符串)你再使用 Base64 转换一下,干啥呢?啥,安全高效

简单来说 Base64 是通过将每 6 位为一个看成一个字节,然后映射到 Base64 的码表中得到相应的字符串。点击这里查看更多关于Base64的详细信息 因为其转换过程的计算方法是公开的,所以在网上你能搜到很多在线 Base64 的转换工具,有的叫 Base64 加密、解密,有的叫 Base64 编码、解码。可能这也是让大家搞混的原因之一吧,至少在我看来不是加密。只是将二进制数据转换成文本数据,便于传输。

Base64 转换过程,参考下表:

表格来自维基百科

Base64加密方法

还有人说,使用 Base64 就不是为了安全,是因为它高效才用的。说这话的人,可能对 Base64 的编码过程不太了解,我来解释一下上面的图片的意思,Base64 是首先将待转换的数据在末尾以补 0 的方式将数据长度补全为 3 的倍数。然后以每 6 位作为一个字节,不足 6 位的最高位补 0,再将其对于到码表中,所以,使用 Base64 只会让数据长度变长,具体变长多少呢?1/3。既然使用 Base64 转换后的数据都变长了,怎么高效?

再多说一点点,仔细看,其实 Base64 不是 64 个字符,是 65 个,除了 a-z、A-Z、0-9 以及两个特殊字符外还有一个 = 作为结束标记。但是 = 不是一定会出现的。

Hash

Hash 平时可能都有用过,但是不太熟悉,甚至,还可能觉得什么把 Hash 跟加密放在一起?是因为 Hash 跟 Base64 一样,也是容易被人混淆的。那么 Hash 到底是什么呢?Hash 在英语中有把……弄乱,切碎的意思。什么意思呢?就是把任意长度的数据映射为固定(有限)长度的数据。比如 I'm a developer 对应的 Hash 值如下:

  • SHA1

    71c25c6e21f9a1571c8aab270d8a4dee3c2a07c1

  • SHA256

    0f7f321e14c9dc026f95e7569dde90dcef988ff44d30ac2dc9e24168e05111b4

  • MD5

    db32e7134744e20e174c9425e627dd10

可以看到,一个字符串有多个 Hash 值,这是什么情况呢?这是因为 Hash 有多种算法,SHA1、SHA256、MD5都是其中一种,还有其他的算法,比如 SHA224,同时不同的算法生成的 Hash 值的长度也不同。哎,那我同一个数据经过 Hash 之后得到的数据,变长了,或是变短了,是不是就是加密?

不好意思,还真不是,为什么呢?因为 Hash 的算法是不可逆的,说不可逆好像也不太合适,就是你只能使用 Hash 算法将 I'm a developer 变成上面几个数据中的一个,但是,你没办法通过 Hash 后的数据再转换到 I'm a developer。哇,听起来有点鸡肋啊,那他能干啥呀。不能加密算了,还产生那么一堆看起来没什么用的东西。别急啊。

因为一旦选定好 Hash 算法之后,Hash 值就是固定的了。所以,Hash 一般用来校验数据。比如,你在网上下载一个文件的时候,有些下载提供商会提供几种算法的 Hash 值,干啥呢。用来保证你下载的文件确定是没有被有心之人篡改后的。因为同样的数据对应的 Hash 值也是一致的,即使是略微的改动也会导致 Hash 值与之前的千差万别。比如I'm a Developer 我只是改了其中一个字母,使用 MD5 算法得到的 Hash 值为:

1b77d24eb81c857f2f5505ca61eda70a

你看,我只是把 d 改为 D,它与之前的 MD5 的值就完全不一样了。

那为什么还有人说,MD5 快被破解了?是这样的,因为 Hash 的被破解,不是真的说能将一个 Hash 后的字符串还原到源数据,而是说找到一种算法,通过这个算法能找到一个与源数据不同但经过 Hash 计算之后得出的 Hash值一致的情况。

连讲了两个都不是加密的东西,再不讲,加密,说不过去了。接下来开始对称加密、非对称加密。

对称加密

对称加密的原理很简单就是加密与解密使用同一个密钥进行。即:使用加密算法与密钥对原数据进行加密,使用解密算法与密钥对密文进行解密。哎,等等,加密算法与解密算法?解释一下,解密算法是加密算法的反向运算。

对称加密原型图

你看,由于加密与解密使用的是同一个密钥,所以安全性在一定程度上得不到保证。必须保证通信双方先拥有一套不被其他人知道的密钥。不过它也是有其他有点的,比如,性能好,计算速度快,不过这个也是在牺牲密钥长度的基础上做的,这么一看,好像优点不是那么明显……

常见的对称加密算法有:DES、3DES、AES、RC5、RC6。其中,DES 因为密钥长度太短已经逐渐被弃用。

非对称加密

刚才说了,对称加密是不能在不安全的网络中直接传输密钥的,那非对称加密呢?它是可以在网络上进行传输密钥的,因为它的密钥是两个。一个公钥,一个私钥。公钥用于在网络上进行传输,私钥留在自己手中用来解密。

非对称加密原型

非对称加密使用进行公钥加密、私钥进行解密。使用公钥对数据进行加密得到密文,使用私钥对密文进行解密得到数据。私钥是能解开公钥加密的数据,公钥也能解开私钥加密的数据。

因为非对称加密中公钥与私钥是可以互相解开的,所以,非对称加密还可以用于数字签名,使用 私钥 对原数据的 Hash 值进行加密,然后,附加在原数据的后面,这样既保证了原数据是可读的,又可以在数据接收完成之后对数据的完整性加以验证。

非对称加密的优点与缺点也很清晰,优点就是能在网络上进行传输自己的密钥,就这一点来说,就已经比对称加密厉害了,因为如果对称加密把自己的密钥放在网络上 进行传输,很有可能被有心之人获取,然后做一些不可描述的事情。非对称加密就不会存在这个问题,因为它是有两个密钥的。这个是优点。缺点是什么呢?就是性能方面相对于对称加密差一点。

常见的算法有:RSA、ElGamal、背包算法、椭圆曲线加密算法。

为什么经过非对称加密后的信息在网络传输中是安全的

这里引入一个场景。A、B 两人通信,C 作为坏人,截获、篡改 A、B 之间的通信内容。

先看看对称加密后的信息在网络传输中为什么是不安全的。

首先,因为对称加密需要双方共同有一套密钥,那么密钥是需要在网络上进行传输的,在这一步,就已经不安全了,因为,一旦 A、B 在网络上传输了密钥,C 一定能获取到,那么此后的所有经过加密的内容对于 C 来说,只是需要去把加密后的数据解开即可。

再来看看如果使用非对称加密该怎么做。

首先通信双方会先把自己的公钥发送给对方,然后使用对方的公钥对数据进行加密后传输。这个时候即使 C 在 A、B 交换公钥的过程中拿到公钥也是没用的,因为公钥是拿来加密的,而要解密就需要 A、B 的私钥了。所以这个时候 C 是不能进行截获的。这样就绝对安全了吗?并非如此,要知道,C 可是同时拥有 A、B 的公钥,那只有公钥能干什么呢?能伪造数据,C 虽然不能将 A、B 通信的内容进行获取、篡改,但是 C 能发送一个全新的数据,然后时候公钥进行加密呀。这样也是能达到欺骗对方的目的。所以这还不是最终的解决方案。

所以最终的解决方案是,使用自己的私钥对已经使用对方公钥的密文再加密一次。之前使用对方的公钥来进行加密,C 还能做到自己伪造一个假的数据,但是现在通信需要使用私钥再次加密了,C 连伪装都做不到了,为什么?因为 C 没有任何一方的私钥。

举个例子,C 使用 B 的公钥对伪装数据进行加密然后发送给 B,这时候 B 拿到数据会先用 A 的公钥来解开(因为在规定中,是先用 B 的公钥加密,然后再使用 A 的私钥进行加密,在解密的时候,就需要先使用 A 的公钥来解密,然后使用 B 的私钥再次解密),但这时候 B 会发现,经过 A 的公钥解密再次经过 B 的私钥解密后数据就完全没法看了。因为在加密的时候少了一个使用 A 的私钥进行加密的环节。

非对称加密有点绕,还是得自己多想想。到这里,已经非常像 HTTPS 了,但还不是,HTTPS 比这个非对称加密还稍微麻烦一点,敬请期待。

本文题图:Photo by Markus Spiske on Unsplash