上一篇博客:计算机科学领域中里程牌式的算法中提到了两处密码学的算法。其中的序言,让我认识到我的专业是计算机科学与技术,那么是否要科普或者说要专攻的方向是否应该是这些方面的内容呢?(而不是软件工程中所学的内容,个人理解,不喜互喷)
借着这个想法,为了更好的理解密码学,因此就看了一篇名为《图解密码学技术》的一本书,书的确讲的很好。在看完之后,就想写下一篇读书笔记,记录自己看完之后的一个总结,同时该书有四百多页,也是为了哪些不想看这么厚的书,这需要看一篇博客即可。
以下图片是受威胁的特性与应对的密码技术
主要原因有以下两点:
密码算法的秘密早晚会公诸于众:①从历史上看,密码算法的秘密最终无一例外地都会被暴露出来。1999 年, DVD 的密码算法 被破解。2007 年,NXP 的非接触式 1C 卡 MIFARE Classic 的密码算法被破解。这些算法最初都是 保密的,然而研究者可以通过逆向工程的手段对其进行分析,并找到漏洞进行破解。RSA 公司开 发的 RC4 密码算法曾经也是保密的,但最终还是有一位匿名人士开发并公开了与其等效的程序。
②一旦密码算法的详细信息被暴露,依靠对密码算法本身进行保密来确保机密性的密码系统 也就土崩瓦解了。反之,那些公开的算法从一开始就没有设想过要保密,因此算法的暴露丝毫 不会削弱它们的强度。
开发高强度的密码算法是非常困难的。①现在世界上公开的被认为强度较高的密码算法,几乎都是经过密码破译者长期尝试破解未 果而存活下来的。因此,如果认为 “公司自己开发的密码系统比那些公开的密码系统更强”,那只能说是过于高估自己公司的能力了。
② 试图通过对密码算法本身进行保密来确保安全性的行为,一般称为隐蔽式安全性( securityby obscurity ), 这种行为是危险且愚蠢的。
③ 反过来说,将密码算法的详细信息以及程序源代码全部交给专业密码破译者,并且为其提供大量的明文和密文样本,如果在这样的情况下破泽一段新的密文依然需要花上相当长的时间, 就说明这是高强度的密码。
无论使用任何密码算法所生成的密文,只要将所有可能的密钥全部尝试一遍,就总有一天 可以破译出来。因此,破译密文所需要花费的时间,与要保密的明文的价值之间的权衡就显得 非常重要。
严格来说,绝对不会被破解的密码算法是存在的,这就是一次性密码本,但它并不是一种实现可用的算法。还有一种技术被认为可能造就完美的密码技术,那就是量子密码
AES是取代前任标准(DES)而成为新标准的一种对称密码算法。全世界的企业和密码学家提交了多个对称密码算法作为AES的候选,最终在2000年从这些候选算法中选出了一种名为“Rijndael”的对称密码算法,并将其确定为了AES。
谈谈投币寄物柜。首先,我们将物品放入寄物柜中。然后,投入硬币并拔出钥匙,就可以将寄物柜关闭了。关闭后的寄物柜,没有钥匙是无法打开的。也就是说,只要有硬币,任何人都可以关闭寄物柜,但寄物柜一旦关闭,再怎么投币也无法打开。打开寄物柜需要使用钥匙,而不是硬币了。
这里,硬币是关闭寄物柜的秘钥(相当于公钥,任何人都可以知道),而钥匙则是打开寄物柜的秘钥(私钥)。
首先想到的方法有如下几种:
公钥密码中,秘钥分为加密秘钥和解密秘钥两种。发送者用机密秘钥对消息进行加密,接收者用解密秘钥对密文进行解密。该机制下:
①发送者只需要加密秘钥。
②接受者只需要解密秘钥。
③解密秘钥不可以被窃听者获取。
④加密秘钥被窃听获取也是没有问题的。
也就是说,解密秘钥从一开始就是有接受者自己保管的,因此只需要加密秘钥发给发送者就可以解决秘钥配送问题了,因为这根本就不需要配送解密秘钥。
大概机制(RSA)可以参考这篇博客:计算机科学领域中里程牌式的算法](https://blog.csdn.net/qq_39838607/article/details/128757526)中的数字签名部分,数字签名与该算法都是RSA,只不过不一样的是数字签名是反过来使用了,也就是用私钥加密,用公钥解密。
所谓中间人攻击,就是主动攻击者 Mallory 混人发送者和接收者的中间,对发送者伪装成 接收者,对接收者伪装成发送者的攻击方式,在这里,Mallory就是 “中间人”
如图
现在,发送者Alice准备向接收者Bob发送一封邮件,为了解决密钥配送问 题,他们使用了公钥密码。Mallory 位于通信路径中,我们假设他能够任意窃听或篡改邮件的内 容,也可以拦截邮件使对方无法接收到。
上述过程可以重复多次,Bob向Alice发送加密邮件时也可能收到同样的攻击,因此Bob即便要发送邮件给Alice以询问她真正的想法,也能被修改。
这种攻击不仅针对RSA,而是可以针对任何公钥密码。在这个过程中,公钥密码并没有被 破译,所有的密码算法也都正常工作并确保了机密性。然而,所谓的机密性并非在 Alice 和 Bob 之间,而是在 Alice 和 Mallory 之间,以及 Mallory 和 Bob 之间成立的。仅靠公钥密码本身,是无法抵御中间人攻击的。我们还需要一种手段来确认所收到的公钥是否真的属于Bob,这种手段被称为认证。
单向散列函数有一个输入和输出,其中输入消息称为消息,输出值称为散列值。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检验消息的完整性。
同时,散列值的长度和消息的长度无关。单向散列函数总是计算出固定长度的散列值。因此,散列值很容易处理和使用。
单向散列值的性质如下
- 使用单向散列函数可以实现完整性的检查,但有些情况下即便能够检查完整性也是没有意 义的。
- 例如,假设主动攻击者 Mallory 伪装成 Alice, 向 Bob 同时发送了消息和散列值。这时 Bob 能够通过单向散列函数检查消息的完整性,但是这只是对 Mallory 发送的消息进行检查,而无 法检查出发送者的身份是否被 Mallory 进行了伪装。也就是说,单向散列函数能够辨别出 “篡 改”,但无法辨别出 "伪装”。
- 当我们不仅需要确认文件的完整性,同时还需要确认这个文件是否真的属于 Alice 时,仅靠完整性检査是不够的,我们还需要进行认证。 用于认证的技术包括消息验证码和数字签名。消息认证码能够向通信对象保证消息没有被篡改,而数字签名不仅能够向通信对象保证消息没有被篡改,还能够向所有第三方做出这样的 保证。
- 认证需要使用密钥,也就是通过对消息附加 Alice 的密钥(只有 Alice 才知道的秘密信息 ) 来确保消息真的属于 Alice。
数字签名的相关内容,在我这篇博客中一致指向的博客中提到了。因此下边主要提到的是消息认证码技术。
①发送者与接受者事先共享秘钥。(使用的方法如上述谈到的,可以是公钥密码算法等)
②发送者根据消息计算MAC值(使用共享秘钥)
③发送者将消息和MAC值发送给接受者。
④接受者根据收到的消息计算MAC值(使用共享秘钥)
⑤接受者将自己计算的MAC值与从发送者的MAC值对比。
⑥如果两个MAC值一致,则接受者可以断定确实是发送者原始的消息(认证成功);如果不一致,则就是认证失败。
假设发送者 Alice 要向接收者 Bob 发送消息,如果使用了消息认证码,接收者 Bob 就能够 断定自己收到的消息与发送者 Alice 所发出的消息是一致的,这是因为消息中的 MAC 值只有用 Al1Ce 和 Bob 之间共享的密钥才能够计算出来,即便主动攻击者 Mallory 篡改消息,或者伪装成 Alice 发送消息,Bob 也能够识别出消息的篡改和伪装。
但是,消息认证码也不能解决所有的问题,例如 “对第三方证明” 和 “防止否认”,这两个 问题就无法通过消息认证码来解决。下面我们来逐一解释一下。
假设 Bob 在接收了来自 Alice 的消息之后,想要向第三方验证者 Victor 证明这条消息的确 是 Alice 发送的,但是用消息认证码无法进行这样的证明,这是为什么呢? •’ ’
首先,Victor 要校验 MAC 值,就需要知道 Alice 和 Bob 之间共享的密钥。
假设 Bob 相信 Victor,同意将密钥告诉 Victor, 即便如此,Victor 也无法判断这条消息是由 Alice 发送的,因为 Victor 可以认为:“即使 MAC 值是正确的,发送这条消息的人也不一定是 Alice, 还有可能是 Bob。”
能够计算出正确MAC值的人只有Alice和Bob, 在他们两个人之间进行通信时,可以断定 是对方计算了 MAC 值,这是因为共享这个密钥的双方之中,有一方就是自己。然而,对于第
三方Victor, Alice或Bob却无法证明是对方计算了MAC值,而不是自己。 使用第 9 章中将要介绍的数字签名就可以实现对第三方的证明。
假设 Bob 收到了包含 MAC 值的消息,这个 MAC 值是用 Alice 和 Bob 共享的密钥计算出来 的,因此 Bob 能够判断这条消息的确来自 Alice。
但是,上面我们讲过,Bob 无法向验证者 Victor 证明这一点,也就是说,发送者 Alice 可以 向Victor声称:“我没有向Bob发送过这条消息。” 这样的行为就称为否认(repudiation)。
Alice 可以说 “这条消息是 Bob 自己编的吧” “说不定 Bob 的密钥被主动攻击者 Mallory 给 盗取了,我的密钥可是妥善保管着呢” 等。说白了,就是 Alice 和 Bob 吵起来了。
即便 Bob 拿 MAC 值来举证,Victor 也无法判断 Alice 和 Bob 谁的主张才是正确的,也就是 说,用消息认证码无法防止否认(nonrepudiation)。在这种情况下,就需要使用数字签名就可以实现防止否认了。
通俗来说,消息认证码确保的是消息被正确转送了没有;数字签名则是确认消息到底是谁写的。
实际上,和对称密码、公钥密码、数字签名等技术相比,生成随机数的技术确实不是很引人注意,但是,随机数在密码技术中扮演者十分重要的角色。
上面三个性质中,越往下就越严格。随机数就是依据这三个性质的有无来进行分类的。如下图
所谓随机性,简单来说就是看上去杂乱无章的性质。我们可以用伪随机数生成器大量生成0到9范围内的整数,然后看一看所生成的数列。如果数列是像0、1、2、3、4、5.6、7、8、 9 、0 、 1 、2…这样不断循环的,那肯定不是杂乱无章的。或者乍一看是杂乱无章的,但实际上 在数列中 0 —次都没有出现,或者整个数列中有一半都是 6, 这样的数列也不能算是杂乱无 章的。
如果伪随机数列中不存在统计学偏差,则我们可以认为这个伪随机数列是随机的。判断一 个伪随机数列是否随机的方法称为随机数测试,随机数测试的方法有很多种。
一般在电脑游戏中使用的随机数只要具备随机性就可以了。此外,在计算机模拟中使用的 随机数虽然需要根据目的来进行随机数测试,但也是只要具备随机性就可以了。然而,密码技术中所使用的随机数,仅仅具备随机性是不够的。
让我们来回忆一下密码技术中使用的随机数需要具备怎样的性质。由’于随机数会被用来生成密钥,因此密钥不能被攻击者看穿。但是,杂乱无章并不代表不会被看穿。
密码中所使用的随机数仅仅具备随机性是不够的,还需要具备避免被攻击者看穿的不可预 测性。不可预测性在英语中叫作 unpredictability, 将这个单词分解之后是这样的:un( 否定 )-pre ( 之前 ) -diet ( 说 ) -ability ( 可能性 )。因此,unpredictability 就是一种 “不可能事先说中” 的性质,即不可预测性。
所谓不可预测性,是指攻击者在知道过去生成的伪随机数列的前提下,依然无法预测出下—个生成出来的伪随机数的性质。其中,“在知道过去生成的伪随机数列的前提下…” 是非常 重要的一点。
现在我们假设攻击者已经知道伪随机数生成器的算法。此外,正如攻击者不知道密钥一样, 他也不知道伪随机数的种子气伪随机数生成器的算法是公开的,但伪随机数的种子是保密的。 在上述假设的前提下,即便攻击者知道过去所生成的伪随机数列,他也 预测出下一个生成 出来的伪随机数— 这就是不可预测性。
那么如何才能编写出具备不可预测性的伪随机数生成器呢?嗯,这是一个很有意思的问题。 其实,不可预测性是通过使用其他的密码技术来实现的。例如,可以通过单向散列函数的单向 性和密码的机密性来保证伪随机数生成器的不可预测性。
所谓不可重现性,是指无法重现和某一随机数列完全相同的数列的性质。如果除了将随机 数列本身保存下来以外,没有其他方法能够重现该数列,则我们就说该随机数列具备不可重现性。
仅靠软件是无法生成出具备不可重现性的随机数列的。软件只能生成伪随机数列,这是因 为运行软件的计算机本身仅具备有限的内部状态。而在内部状态相同的条件下,软件必然只能 生成相同的数,因此软件所生成的数列在某个时刻一定会出现重复。首次出现重复之前的数列 长度称为周期,对于软件所生成的数列,其周期必定是有限的。当然,这个周期可能会很长, 但总归还是有限的。凡是具有周期的数列,都不具备不可重现性。
要生成具备不可重现性的随机数列,需要从不可重现的物理现象中获取信息,比如周围的温度和声音的变化、用户移动的鼠标的位置信息、键盘输入的实践间隔等,根据从这些硬件中所获取的信息而生成的数列,一般可以认为是具备不可重现性的随机数列。
随机数可以通过硬件来生成,也可以通过软件来生成。
通过硬件生成的随机数列,是根据传感器收集的热量、声音的变化等事实上无法预测和重现的 自然现象信息来生成的。像这样的硬件设备就称为随机数生成器(Random Number Generator, RNG )。
而可以生成随机数的软件则称为伪随机数生成器(Pseudo Random Number Generator, PRNG)0 因为仅靠软件无法生成真随机数,因此要加上一个 “伪” 字。
伪随机数生成器的结构如下,伪随机数生成器具有“内部状态”,并根据外部输入的“种子”来生成伪随机数列。
伪随机生成器的具体实现有主要有如下几种
无论是对称密码还是公钥密码,密码的作用都是确保机密性。由于确保较长的明文整体的 机密性很困难,因此我们用密码将明文转换成密文。这样一来,我们就不必保护明文本身了。 相对地,我们则需要保护加密时所使用的密钥。通过保护较短的密钥来保护较长的明文,这样 的做法可以称为机密性的压缩。
单向散列函数是用于确认完整性的。我们不必检查较长的明文的完整性,只要检查散列值 就能够确认完整性了。通过检查较短的散列值来确认较长的明文的完整性,这样的做法可以称为完整性的压缩。
消息认证码和数字签名都是用于认证的技术 , 但我们并不是直接对较长的消息本身进行认 证, 而是通过将较长的消息与密钥结合起来,生成较短的比特序列(认证符号 ),再通过认证符 号进行认证。在消息认证码中,MAC 值就是认证符号;而在数字签名中,签名就是认证符号。 通过较短的认证符号来对较长的消息进行认证,这样的做法可以称为认证的压缩。
那么伪随机数生成器又是怎样的呢?在伪随机数生成器中,所生成数列的不可预测性是非常重要的。要大量生成具备不可预测性的随机数列非常困难,于是我们通过将种子输人伪随机数生成器,生成具备不可预测性的伪随机数列。也就是说,为了对伪随机数列赋予不可预测性,我们使用了随机数种子,这可以称为不可预测性的压缩。反过来说,伪随机数生成器是将种子所具备的不可预测性进行了扩张。
这里的观点很重要,因此我们从另一个角度来总结一下。
• 密钥是机密性的精华
• 散列值是完整性的精华
• 认证符号(MAC值和签名)是认证的精华
• 种子是不可预测性的精华
如下表
比特币之 所以能够成为一种流通的货币,完全依赖于全世界所有比特币用户组成的 P2P 网络 ( Peer to Peer Network)。也就是说,全世界所有比特币用户的计算机(node或者peer)共同保存、验证 和使用支撑比特币体系的所有必要信息。
与其说比特币是一种货币,不如说比特币是一种基于 P2P 网络的支付结算系统,这样更易 于人们理解其本质。比特币用户通过使用比特币这一支付结算系统实现了价值的转移,因此比 特币看上去才具备了货币的特征。
区块链就是保存比特币全部交易记录的公共账簿。全世界使用比特币进行的所有交易被记录在一本公共账簿中。顾名思义,区块链即使将交易以区块为单位组织起来的。
区块的添加。比特币的首付款是以交易为单位来进行的,若干条交易会合并为一个区块,并被添加到区块链中。当P2P网络确认区块的添加后,相应的交易也就成立了。如下图:
1. 一个区块是由若干条交易以及一个区块头所组成的,区块头中保存了 “上一个区块的区块 头的散列值”。以图 15-4 中的区块 2 为例,其中区块头 2 中保存的散列值 H2 就是根据它前面的 区块 1 的区块头 1 计算出来的。
2. 此外,区块头中还保存着 “本区块所有交易的整体散列值” 例如,区块头2中的散列值 T2 就是根据区块 2 中记录的所有交易数据计算出的散列值。
3. 区块头中还保存着一个名为 nonce 的任意数值,以及时间戳(图中省略 )等信息。
4. 假设区块 2 中记录的某一条交易中的 1 个比特被修改,那么散列值 T2 就需要重新计算,这 样一来区块头2的内容就会发生变化,因此区块头3中的散列值H3也需要重新计算。也就是 说,一旦对区块链中的数据进行任何改动,都需要重建所改动的区块之后的所有区块的数据。 由此可见,区块头中的两个散列值有效增加了篡改区块链数据的难度。
交易成立的前提是一方必须拥有一定量的比特币。那么比特币是如何拥有的呢?
000000000000000007780B6F7817C431309EDED44F51223352D86A4436023913