《图解密码技术》学习笔记
#读书笔记#
小w,最近我们的系统安全漏洞怎么这么多,前几天还收到客户投诉我们平台泄露他的个人信息,这个问题不解决掉年终你就自己看着办吧。新上任的高P发话了,作为混迹职场多年的老油条怎么也要做点“面子工程”,表示表示。可这问题怎么解呢,突然我想起之前的密码学总结,赶紧复习一下,也给星球的各位来个分享。
前言
信息安全是互联网能够蓬勃发展的重要基石,我们日常工作中总会遇到敏感信息的保存和传递,如何有效保证信息的安全是业务开发领域必须关注的。
本文通过对《图解密码技术》学习,整理出工作中经常遇到的信息安全问题,介绍了技术方案及大致原理,便于对信息安全领域有系统性的理解。
密码技术适用的问题场景

上图概括了信息安全中常见风险及解决思路,接下来将逐一介绍。
密码
正如保险柜的钥匙可以保护保险柜中存放的贵重物品一样,密码中的密钥可以保护你的重要数据。即使保险箱再坚固,如果钥匙被盗,则里面的贵重物品也会被盗。同样地,我们也必须注意不要让密码被他人窃取。
密码算法
计算机的操作对象并不是文字,而是由 0和1排列而成的比特序列。无论是文字、图像、 声音、视频还是程序,在计算机中都是用比特序列来表示的。执行加密操作的程序,就是将表示明文的比特序列转换为表示密文的比特序列。
加解密的核心要素: 密钥 + 密码算法。
从明文生成密文的步骤,也就是加密的步骤,称为 “加密算法”,而解密的步骤则称为 “解密算法”。加密、解密的算法合在一起统称为密码算法。明文通过加密算法,和输入的“参数” 密钥进行运算,输出无法被直接读懂的密文。
不要使用保密的密码算法!我们不应该制作或使用任何保密的密码算法,而是应该使用那些已经公开的、被公认为强度较高的密码算法
合格的密码算法是一把可以广泛使用的高质量的锁,即使清楚其内部结构(算法源码)和运作原理,在没有钥匙的情况下仍无法被打开。如果保密则意味着它无法被广泛应用。
对称密码
XOR
XOR运算(异或运算)是一种比较典型的对称加解密的。
- 0 XOR 0 = 0
- 0 XOR 1 = 1
- 1 XOR 0 = 1
- 1 XOR 1 = 0
- 看运算规律:由于两个相同的数进行XOR运算的结果一定为0,因此如果将A XOR B 的结果再与B进行 X0R运算,则结果会变回A。
- 这和加密、解密的步骤非常相似。
- 将明文A用密钥B进行加密,得到密文A XOR B 。
- 将密文 A XOR B 用密钥 B 进行解密(A XOR B )XOR B ,得到明文 A。
对称加密算法
- DES (不推荐)
- DES 是一种将64比特的明文加密成64比特的密文的对称密码算法,它的密钥长度是56比特。
- 尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质上其密钥长度是56比特。
- DES是以64比特的明文(比特序列)为一个单位来进行加密的,这个64比特的单位称为分组。一般来说,以分组为单位进行处理的密码算法称为分组密码(block cipher),DES就是分组密码的一种。
由于DES的密文可以在短时间内被破译,因此除了用来解密原有密文,新场景不应该再使用DES了
- 3DES (不推荐)
- 三重DES( triple-DES)是为了增加DES的强度,将DES重复3次所得到的一种密码算法, 也称为 TDEA ( Triple Date Encryption Algorithm ),通常缩写为 3DES。
- 明文经过三次 DES 处理才能变成最后的密文,由于 DES 密钥的长度实质上是 56 比特,因 此三重 DES 的密钥长度就是 56 x 3=168 比特。
- 三重DES并不是进行三次DES加密(加密—加密—加密),而是加密—解密—加密的过程。在加密算法中加人解密操作让人感觉很不可思议,实际上这个方法是 IBM 公司设计出来的,目的是为了让三重 DES 能够兼容普通的DES。
- 尽管三重 DES 目前还被某些机构使用,但其处理速度不高,除了特别重视向下兼容性的情况以外,很少被用于新的用途。
- AES (推荐)
- AES ( Advanced Encryption Standard )是取代其前任标准( DES )而成为新标准的一种对称密码算法。
- AES 是由全世界的企业和密码学家参加选拔出来的加密算法,这其中也包括AES竞选的参加者。参加竞选的密码算法是由包括参加者在内的整个密码学社区共同进行评审的。
- Rijndael是由比利时密码学家 Joan Daemen和 Vincent Rijmen设计的分组密码算法,于2000年被选为新一代的标准密码算法—AES。Rijndael的分组长度和密钥长度可以分别以32比特为单位在128 比特到256比特的范围内进行选择。不过在AES的规格中,分组长度固定为128比特,密钥长度只有128、192和256 比特三种。
- 和DES—样,Rijndael算法也是由多个轮构成的,其中每一轮分为SubBytes、ShiftRows、 MixColumns 和 AddRoundKey 共 4 个步骤。DES使用Feistel网络作为其基本结构,而 Rijndael没有使用Feistel 网络,而是使用了 SPN 结构。
- 对于 Rijndael 来说,可能会出现以前并不存在的新的攻击方式。Rijndael 的算法背后有着严谨的数学结构,也就是说从明文到密文的计算过程可以全部用公式来表达,这是之前密码算法都不具备的性质。如果Rijndael的公式能够通过数学运算来求 解,那也就意味着 Rijndael 能够通过数学方法进行破译,而这也就为新的攻击方式的产生提 供了可能。不过,这也只是一种假设而已,实际上到现在为止还没有出现针对 Rijndael 的有效攻击。
对称加密方案选择
首先,DES 不应再用于任何新的用途,因为随着计算机技术的进步,现在用暴力破解法已经能够在较短时间内完成对DES 的破译。
其次,我们也没有理由将三重DES 用于任何新的用途,尽管在一些重视兼容性的环境中还会继续使用,但它会逐渐被 AES 所取代。
现在大家应该使用的算法是AES(Rijndael),因为它安全、快速,而且能够在各种平台上工作。
ps:AES 最终候选算法应该可以作为AES 的备份。和 Rijndael —样,这些密码算法也都经过了严格的测试,且没有发现任何弱点。但 NIST 最终选择的标准只有 Rijndael, 并没有官方认可将其他最终候选算法作为备份来使用。
非对称密码
比较形象的例子是投币寄物柜。首先,将物品放人寄物柜中。然后,投入硬币并拔出钥匙,就可以将寄物柜关闭了。关闭 后的寄物柜,没有钥匙是无法打开的。只要有硬币,任何人都可以关闭寄物柜,但寄物柜一旦被关闭,再怎么投币也无法打开。 打开寄物柜需要使用钥匙,而不是硬币。
因此可以认为硬币是关闭寄物柜的公钥,而钥匙则是打开寄物柜的私钥。
适用场景
通过公钥密码来解决对称密钥配送问题。只要拥有加密密钥,任何人都可以进行加密,但没有解密密钥是无法解密的。接收者事先将加密密钥发送给发送者,这个加密密钥即便被窃听者获取也没有问题。发送者使用加密密钥对通信内容进行加密并发送给接收者,而只有拥有解密密钥的人( 即接收者本人 )才能够进行解密。这样一来,对称密码的密钥配送问题,就可以通过使用公钥密码来解决。
公钥和私钥是一一对应的,一对公钥和私钥统称为密钥对(key pair)。由公钥进行加密的密文, 必须使用与该公钥配对的私钥才能够解密。密钥对中的两个密钥之间具有非常密切的关系,因此公钥和私钥是不能分别单独生成的。
公钥通信流程

非对称加密算法
RSA是一种公钥密码算法,它的名字是由它的三位开发者,即 RonRivest 、 Adi Shamir 和 Leonard Adleman 的姓氏的首字母组成的( Rivest-Shamir-Adleman )。RSA 可以被用于公钥密码和数字签名。
RSA加密
在RSA中,明文、密钥和密文都是数字。RSA的加密过程可以用下列公式来表达:
密文 = 明文E mod N
即 RSA 的密文是对代表明文的数字的 E 次方求 mod N 的结果。换句话说,就是将明文和自己做E次乘法,然后将其结果除以N求余数,这个余数就是密文。
加密公式中出现的两个数— E和N,到底都是什么数呢?RSA的加密是求明文的E次方mod N,因此只要知道E和N这两个数,任何人都可以完成加密的运算。所以说,E和N是 RSA 加密的密钥,也就是说,E和N的组合就是公钥。
RSA解密
RSA 的解密和加密一样简单,可以用下面的公式来表达:
明文=密文D mod N
也就是说,对表示密文的数字的 D次方求 mod N 就可以得到明文。换句话说,将密文和自己做D次乘法,再对其结果除以况求余数,就可以得到明文。这里所使用的数字N和加密时使用的数字N是相同的。数D和数N组合起来就是RSA的解密密钥,因此D和N的组合就是私钥。

破解方式
1. 通过密文来求得明文
RSA 的加密过程如下:
密文 = 明文E mod N
由于密码破译者知道密文E 和 N, 那么有没有一种方法能够用E次方 mod N 之后的密文求出原来的明文呢?如果没有modN的话,即: 密文 = 明文E,过密文求明文的难度不大,因为这可以被看作是一个求对数的问题。 但是,加上modN之后,求明文就变成了求离散对数的问题,这是非常难的,目前还没有发现求离散对数的高效算法。
2. 通过暴力破解来找出D(密钥)
暴力破解的难度会随着D的长度增加而变大,当D足够长时,就不可能在现实的时间内通过暴力破解找出数D。
现在,RSA中所使用的p 和q的长度都是1024比特,N的长度为2048比特以上。由于 E 和D的长度可以和N差不多,因此要找出 D, 就需要进行2048比特以上的暴力破解。要在这样的长度下用暴力破解找出D是极其困难的。
3. 对N进行质因数分解攻击
p和q不能被密码破译者知道,但是N=p x q,而且N是公开的,那么能不能由N求出p和q呢?
p 和 q 都是质数,因此由 N求 p 和 q 只能通过将 N 进行质因数分解来完成。我们可以说:
一旦发现了对大整数进行质因数分解的高效算法,RSA 就能够被破译
如果能够快速地对大整数进行质因数分解,就能够将N 分解成质因数 p 和 q,然后就可以 求出 D, 这是事实。
然而,现在我们还没有发现对大整数进行质因数分解的高效算法,而且也尚未证明质因数分解是否真的是非常困难的问题,甚至也不知道是否存在一种分解质因数的简单方法。
4. 中间人攻击
所谓中间人攻击,就是主动攻击者混入发送者和接收者的中间,对发送者伪装成接收者,对接收者伪装成发送者的攻击方式。
这种攻击不仅针对 RSA,而是可以针对任何公钥密码。在这个过程中,公钥密码并没有被破译,所有的密码算法也都正常工作并确保了机密性。然而,所谓的机密性并非在 Alice 和 Bob 之间,而是在 Alice 和 Mallory 之间,以及 Mallory 和 Bob 之间成立的。仅靠公钥密码本身,是无法防御中间人攻击的。
要防御中间人攻击,还需要一种手段来确认所收到的公钥是否真的属于 Bob, 这种手段称为认证。在这种情况 下 , 我们可以使用公钥的证书。
信息认证
信息防篡改
很多时候我们会从网上获取大量信息,那么我们怎么知道获取的文件是真实的,不是有“中间人”创建虚假恶意的信息来欺骗我们呢?
在刑事侦查中,侦查员会用到指纹。通过将某个特定人物的指纹与犯罪现场遗留的指纹进 行对比.就能够知道该人物与案件是否存在关联。针对计算机所处理的消息,有时候我们也需要用到 “指纹”。当需要比较两条消息是否一致 时,我们不必直接对比消息本身的内容,只要对比它们的 “指纹” 就可以了。
在信息安全领域同样存在一种采集文件 “指纹” 的技术:单向散列函数。单向散列函数所生成 的散列值,就相当于消息的 “指纹”。
单向散列函数
单向散列函数(one-way hash function)有一个输入和一个输出,其中输人称为消息(message), 输出称为散列值(hash value)。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。

通过使用单向散列函数,即便是确认几百 MB 大小的文件的完整性,也只要对比很短的散列值就可以了。
单向散列函数性质
1. 根据任意长度的消息计算出固定长度的散列值
2. 能够快速计算出散列值
3. 消息不同散列值也不同 (难以发现碰撞的性质称为抗碰撞性collision resistance,密码技术中所使用的单向散列函数,都需要具备抗碰撞性)
4. 具备单向性
单向散列函数必须具备单向性(one-way)。单向性指的是无法通过散列值反算出消息的性质。
单向散列函数应用场景
检测下载文件(如:软件)是否被篡改。

单向散列函数实现方案
1. MD4、MD5
MD4 是由 Rivest 于 1990 年设计的单向散列函数,能够产生 128 比特的散列值,MD5 是由 Rivest 于 1991 年设计的单项散列函数,能够产生 128 比特的散列值。
MD5 的强抗碰撞性已经被攻破,也就是说,现在已经能够产生具备相同散列值的两条不同的消息,因此它也已经不安全了。
ps: MD4 和 MD5 中的 MD 是消息摘要( Message Digest )的缩写.
2. SHA系列算法
SHA-1是设计的一种能够产生 160 比特的散列值的单向散列函数,SHA-1 已经被列人 “可谨慎运用的密码清单”,即除了用于保 持兼容性的目的以外,其他情况下都不推荐使用。
SHA-256、SHA-384和SHA512都是由NIST设计的单向散列函数,它们的散列值长度分别为256比特、384比特和512比特。
这些单向散列函数合起来统称SHA-2,SHA-2 还尚未被攻破。
SHA-3( Secure Hash Algorithm-3)是一种作为新标准发布的单向散列函数算法,用来替代在理论上已被找出攻击方法的 SHA-1算法。
单向散列函数局限性
使用单向散列函数可以实现完整性的检查,但有些情况下即便能够检查完整性还是不够。
例如,假设主动攻击者 Mallory 伪装成 Alice, 向 Bob 同时发送了消息和散列值。这时 Bob 能够通过单向散列函数检查消息的完整性,但是这只是对 Mallory 发送的消息进行检查,而无 法检查出发送者的身份是否被 Mallory 进行了伪装。也就是说,单向散列函数能够辨别出 “篡改”,但无法辨别出 "伪装”。
数字签名
数字签名是一种将相当于现实世界中的盖章、 签字的功能在计算机世界中进行实现的技术。使用数字签名可以识别篡改和伪装,还可以防止行为否认。
数字签名的验证逻辑
数字签名技术中,包含两种行为:
- 生成消息签名的行为
- 验证消息签名的行为
在数字签名中,生成签名和验证签名这两个行为需要使用各自专用的密钥来完成。数字签名对签名密钥和验证密钥进行了区分,使用验证密钥是无法生成签名的。签名密钥只能由签名的人持有,而验证密钥则是任何需要验证签名的人都可以持有。
数字签名中也同样会使用公钥和私钥组成的密钥对,不过这两个密钥的用法和公钥密码是相反的,即用私钥加密相当于生成签名,而用公钥解密则相当于验证签名。

数字签名的使用方式
1. 直接对消息签名的方法
Alice需要事先生成一个包括公钥和私钥的密钥对, 而需要验证签名的 Bob 则需要得到Alice 的公钥。在此基础上,签名和验证的过程如下

2. 对消息的散列值签名的方法
直接对消息签名的方法,但这种方法需要对整个消息进行加密非常耗时,因为公钥密码算法本来就非常慢。那么我们可以利用之前的单向散列函数进行信息摘要,对摘要后的信息加签,这样可以大大提高效率。

证书
我们了解了非对称加密以及数字签名。无论是公私钥密码还是数字签名,其中公钥都扮演了重要的角色。然而,如果不能判断自己手上的公钥是否合法,就有可能遭到中间人攻击。证书就是用来对公钥合法性提供证明的技术。
证书的应用场景
下面我们来通过证书的代表性应用场景来理解证书的作用。下图展示了Alice向Bob发送密文的场景,在生成密文时所使用的Bob的公钥是通过认证机构获取的。而这样的前提在于认证机构必须是可信的。

证书标准规范

针对证书的攻击
1. 在公钥注册之前进行攻击
要防止这种攻击,我们可以采用下面的做法:例如 Bob 可以在将公钥发送给认证机构进行注册时,使用认证机构的公钥对 Bob 的公钥进行加密。此外,认证机构在确认 Bob 的身份时, 也可以将公钥的指纹一并发送给 Bob 请他进行确认。
2. 攻击者伪装成认证机构进行攻击
如果认证机构本身不可信,即便证书合法,其中的公钥也不能使用。虽然这一点是理所当然的,但是要防范这种攻击却需要 用户自己多加留心才行,她必须要注意自己所得到的证书是哪个认证机构颁发的,这个认证机构是否可信。
ps: 目前知名的浏览器会内置可信的证书机构自动做验证。
总结
正如本文开头提及的,信息安全是互联网能够发展的基石,信息的高效传递促进社会发展进步的前提是真实有效。同时用户信息也需要被重点保护,防止泄漏被恶意使用。在日常的开发中,保持对信息安全的敬畏才能让业务走的更稳定长远。

