密码学技术
- 前言
- 基础术语
- 不要使用保密的密码算法
- 任何密码总有一天都会被破解
- 对称密码(共享秘钥密码)
- AES
- 总结
- 公钥密码 --- 用公钥加密,私钥解密
- 秘钥配送问题
- 公钥密码
- 中间人攻击
- 认证
- 单向散列函数--- 消息的指纹
- 单向散列函数的实际应用
- 单向散列函数无法解决的问题。
- 消息认证码
- 什么事消息认证码
- 消息认证码无法解决的问题
- 对第三方证明
- 防止否认
- 密钥
- 什么是密钥
- 各种不同的密钥
- 随机数 --- 不可预测的源泉
- 随机数的性质
- 随机性
- 不可预测性
- 不可重现性
- 伪随机数生成器
- 密码技术与实现社会
- 密码技术小结
- 6中基本的密码技术
- 密码技术与压缩技术
- 比特币
- 区块链
- 挖矿
前言
上一篇博客:计算机科学领域中里程牌式的算法中提到了两处密码学的算法。其中的序言,让我认识到我的专业是计算机科学与技术,那么是否要科普或者说要专攻的方向是否应该是这些方面的内容呢?(而不是软件工程中所学的内容,个人理解,不喜互喷)
借着这个想法,为了更好的理解密码学,因此就看了一篇名为《图解密码学技术》的一本书,书的确讲的很好。在看完之后,就想写下一篇读书笔记,记录自己看完之后的一个总结,同时该书有四百多页,也是为了哪些不想看这么厚的书,这需要看一篇博客即可。
基础术语
- 加密之前的消息称为明文,加密之后的消息称为密文。
- 从明文生成密文的步骤,也就是加密的步骤,称为“加密算法”,而解密的步骤则称为“解密算法”。加密、解密的算法结合在一块统称为密码算法。
- 秘钥:密码算法中需要秘钥。是一串很大的数字。无论是加密还是解密的时候,都需要知道秘钥。
- 依据秘钥的使用方法,可以将密码分为对称密码和公钥密码两种。**对称密码:**是指在加密和解密时使用同一秘钥的方式。非对称密码::也叫公钥密码。是指在加密和解密时使用不同秘钥的方式。
以下图片是受威胁的特性与应对的密码技术
不要使用保密的密码算法
主要原因有以下两点:
-
密码算法的秘密早晚会公诸于众:①从历史上看,密码算法的秘密最终无一例外地都会被暴露出来。1999 年, DVD 的密码算法 被破解。2007 年,NXP 的非接触式 1C 卡 MIFARE Classic 的密码算法被破解。这些算法最初都是 保密的,然而研究者可以通过逆向工程的手段对其进行分析,并找到漏洞进行破解。RSA 公司开 发的 RC4 密码算法曾经也是保密的,但最终还是有一位匿名人士开发并公开了与其等效的程序。
②一旦密码算法的详细信息被暴露,依靠对密码算法本身进行保密来确保机密性的密码系统 也就土崩瓦解了。反之,那些公开的算法从一开始就没有设想过要保密,因此算法的暴露丝毫 不会削弱它们的强度。 -
开发高强度的密码算法是非常困难的。①现在世界上公开的被认为强度较高的密码算法,几乎都是经过密码破译者长期尝试破解未 果而存活下来的。因此,如果认为 “公司自己开发的密码系统比那些公开的密码系统更强”,那只能说是过于高估自己公司的能力了。
② 试图通过对密码算法本身进行保密来确保安全性的行为,一般称为隐蔽式安全性( securityby obscurity ), 这种行为是危险且愚蠢的。
③ 反过来说,将密码算法的详细信息以及程序源代码全部交给专业密码破译者,并且为其提供大量的明文和密文样本,如果在这样的情况下破泽一段新的密文依然需要花上相当长的时间, 就说明这是高强度的密码。
任何密码总有一天都会被破解
无论使用任何密码算法所生成的密文,只要将所有可能的密钥全部尝试一遍,就总有一天 可以破译出来。因此,破译密文所需要花费的时间,与要保密的明文的价值之间的权衡就显得 非常重要。
严格来说,绝对不会被破解的密码算法是存在的,这就是一次性密码本,但它并不是一种实现可用的算法。还有一种技术被认为可能造就完美的密码技术,那就是量子密码
对称密码(共享秘钥密码)
- 共享秘钥就说明这个秘钥既可以加密有可用解密,也就是说这个操作是可以通过秘钥还原的。而这,众多的对称密码算法中,都是基于XOR操作实现的。因为两次XOR操作相当于没有做过任何操作。
AES
AES是取代前任标准(DES)而成为新标准的一种对称密码算法。全世界的企业和密码学家提交了多个对称密码算法作为AES的候选,最终在2000年从这些候选算法中选出了一种名为“Rijndael”的对称密码算法,并将其确定为了AES。
- 参加AES竞选是有条件的,也就是被选为AES的密码算法必须无条件地免费供全世界使用。
- AES的选拔过程是对全世界公开的。像这样通过竞争来实现标准化的方式,正是密码算法选拔的正确方式。由世界最高水平的密码学家共同尝试破译,依然未能找到弱点,只有这样的事实才能证明一种密码算法的强度。
总结
- 对称密码主要有DES,三重DES、AES。这几个密码算法,都只能将固定长度的分组进行加密。当需要加密的明文长度超过分组长度的时候,就需要对密码算法进行迭代了。
- 使用一种秘钥空间巨大,且在算法上没有弱点的对称密码,就可以通过密文来确保明文的机密性。巨大的秘钥空间能够抵御暴力破解,算法上没有弱点则可以抵御其他类型的攻击。
- 用对称密码进行通信时,还会出现秘钥的配送问题,也就是我们如何将秘钥安全地发送给接受者。(这就需要公钥密码技术了)
公钥密码 — 用公钥加密,私钥解密
谈谈投币寄物柜。首先,我们将物品放入寄物柜中。然后,投入硬币并拔出钥匙,就可以将寄物柜关闭了。关闭后的寄物柜,没有钥匙是无法打开的。也就是说,只要有硬币,任何人都可以关闭寄物柜,但寄物柜一旦关闭,再怎么投币也无法打开。打开寄物柜需要使用钥匙,而不是硬币了。
这里,硬币是关闭寄物柜的秘钥(相当于公钥,任何人都可以知道),而钥匙则是打开寄物柜的秘钥(私钥)。
秘钥配送问题
首先想到的方法有如下几种:
- 通过事先共享秘钥来解决。但是这个方法的局限性是比较大的。
- 通过秘钥分配中心来解决。该方法的局限性是,当秘钥增多,秘钥分配中心的负荷也会随之增加。同时如果秘钥分配中心的计算机发生故障,则与之关联的加密通信也会瘫痪。当然,如果秘钥分配中心被攻破的话,那么与之关联的加密通信也会被破译。
- 通过迪菲-赫尔曼密钥交换机制(Diffile-Hellman)来解决。较为具体介绍该算法是在计算机科学领域中里程牌式的算法这篇博客中。
- 通过公钥密码来解决。
公钥密码
公钥密码中,秘钥分为加密秘钥和解密秘钥两种。发送者用机密秘钥对消息进行加密,接收者用解密秘钥对密文进行解密。该机制下:
①发送者只需要加密秘钥。
②接受者只需要解密秘钥。
③解密秘钥不可以被窃听者获取。
④加密秘钥被窃听获取也是没有问题的。
也就是说,解密秘钥从一开始就是有接受者自己保管的,因此只需要加密秘钥发给发送者就可以解决秘钥配送问题了,因为这根本就不需要配送解密秘钥。
大概机制(RSA)可以参考这篇博客:计算机科学领域中里程牌式的算法](https://blog.csdn.net/qq_39838607/article/details/128757526)中的数字签名部分,数字签名与该算法都是RSA,只不过不一样的是数字签名是反过来使用了,也就是用私钥加密,用公钥解密。
- 公钥和私钥是一一对应的,一堆公钥和私钥统称为密钥对。由公钥加密的密文,必须使用与该公钥配对的私钥才能解密。密钥对中的两个秘钥之间有着非常密切的关系----数学上的关系-----因此公钥和私钥是不能分别单独生成的。
- 公钥密码的使用者需要生成一个包括公钥和秘钥的秘钥对,其中公钥会被发送给别人,而私钥则仅供自己使用。具体流程如下图
- 公钥密码存在的问题主要有两个:①我们需要判断所得到的的公钥是否正确合法,这个问题被称之为公钥认证问题;②它的处理速度只要对称密码的几百分之一。(一种方式就是混合使用两种算法,使用公钥密码算法来传输对称算法的共享公钥(一般为会话密码),对于明文则使用对称算法来加密。该方式也称为混合密码系统)
中间人攻击
所谓中间人攻击,就是主动攻击者 Mallory 混人发送者和接收者的中间,对发送者伪装成 接收者,对接收者伪装成发送者的攻击方式,在这里,Mallory就是 “中间人”
如图
现在,发送者Alice准备向接收者Bob发送一封邮件,为了解决密钥配送问 题,他们使用了公钥密码。Mallory 位于通信路径中,我们假设他能够任意窃听或篡改邮件的内 容,也可以拦截邮件使对方无法接收到。
- Alice向Bob发送邮件索取公钥。
“ To Bob : 请把你的公钥发给我 D From Alice” - Mallory 通过窃听发现 Alice 在向 Bob 索取公钥。
- Bob 看到 Alice 的邮件,并将自己的公钥发送给 Alice。
“ To Alice: 这是我的公钥。From Bob” - Mallory拦gBob的邮件,使其无法发送给A】iCe。然后,他悄悄地将Bob的公钥保存
起来,他稍 会用到Bob的公钥。 - Mallory 伪装成 Bob,将自己的公钥发送给 Alice。
“ To Alice: 这是我的公钥。From Bob”(其实是 Mallory ) - Alice将自己的消息用Bob的公钥(其实是Mallory的公钥)进行加密。
“ To Bob: 我爱你D From Alice”
但是, Alice 所持有的并非 Bob 的公钥而是 Mallory 的公钥,因此 Alice 是用 Mallory 的 公钥对邮件进行加密的。 - Alice 将加密后的消息发送给 Bob。
- Mallory 拦截 Alice 的加密邮件。这封加密邮件是用 Mallory 的公钥进行加密的,因此
Mallory 能够对其进行解密,于是 Mallory 就看到了 Alice 发给 Bob 的情书。 - Mallory 伪装成 Alice 写一封假的邮件。
“ To Bob: 我讨厌你。From Alice”(其实是 Mallory ) 然后,他用4中保存下来的 Bob 的公钥对这封假邮件进行加密,并发送给 Bob。 - Bob 用自己的私钥对收到的邮件进行解密,然后他看到消息的内容是:
“ To Bob : 我讨厌你。From Alice” 他伤心极了。
上述过程可以重复多次,Bob向Alice发送加密邮件时也可能收到同样的攻击,因此Bob即便要发送邮件给Alice以询问她真正的想法,也能被修改。
这种攻击不仅针对RSA,而是可以针对任何公钥密码。在这个过程中,公钥密码并没有被 破译,所有的密码算法也都正常工作并确保了机密性。然而,所谓的机密性并非在 Alice 和 Bob 之间,而是在 Alice 和 Mallory 之间,以及 Mallory 和 Bob 之间成立的。仅靠公钥密码本身,是无法抵御中间人攻击的。我们还需要一种手段来确认所收到的公钥是否真的属于Bob,这种手段被称为认证。
认证
单向散列函数— 消息的指纹
单向散列函数有一个输入和输出,其中输入消息称为消息,输出值称为散列值。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检验消息的完整性。
同时,散列值的长度和消息的长度无关。单向散列函数总是计算出固定长度的散列值。因此,散列值很容易处理和使用。
单向散列值的性质如下
- 根据任意长度的消息计算出固定长度的散列值。
- 能够快速计算出散列值。
- 消息不同散列值也不同。为了确认完整性,消息中哪怕只有1比特的改变,也必须有很高的概率产生不同的散列值。两个不同消息产生同一个散列值的情况称为碰撞。
- 弱抗碰撞性指的是 要找到和该条消息具有相同散列值的另外一条消息是非常困难的。
- 强抗碰撞性指的是 要找到散列值相同的两条不同的消息是非常困难的。密码技术中所使用的的单向散列函数,不仅要具备弱抗碰撞性,还必须具备强抗碰撞性。
- 具备单向性。指的是无法通过散列值反算出消息的性质。
单向散列函数的实际应用
- 基于口令的加密。单向散列函数也被用于基于口令的加密( Password Based Encryption , PBE )。
PBE 的原理是将口令和盐( salt, 通过伪随机数生成器产生的随机值 )混合后计算其散列 值,然后将这个散列值用作加密的密钥。通过这样的方法能够防御针对口令的字典攻击。 - 消息认证码。使用单向散列函数可以构造消息认证码。消息认证码是将 “发送者和接收者之间的共享密钥” 和 “消息” 进行混合后计算出的散列 值。使用消息认证码可以检测并防止通信过程中的错误、篡改以及伪装。消息认证码在 SSL/TLS 中也得到了运用。
- 数字签名。在进行数字签名时也会使用单向散列函数。
数字签名是现实社会中的签名和盖章这样的行为在数字世界中的实现。数字签名的处理过 程非常耗时,因此一般不会对整个消息内容直接施加数字签名,而是先通过单向散列函数计算 出消息的散列值,然后再对这个散列值施加数字签名。 - 伪随机数生成器。使用单向散列函数可以构造伪随机数生成器。
密码技术中所使用的随机数需要具备 “事实上不可能根据过去的随机数列预测未来的随机 | 数列” 这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。 - —次性口令。使用单向散列函数可以构造一次性口令(one-time password)0 一次性口令经常被用于服务 器对客户端的合法性认证。在这种方式中,通过使用单向散列函数可以保证口令只在通信链路 上传送一次( one-time ),因此即使窃听者窃取了口令,也无法使用。
单向散列函数无法解决的问题。
- 使用单向散列函数可以实现完整性的检查,但有些情况下即便能够检查完整性也是没有意 义的。
- 例如,假设主动攻击者 Mallory 伪装成 Alice, 向 Bob 同时发送了消息和散列值。这时 Bob 能够通过单向散列函数检查消息的完整性,但是这只是对 Mallory 发送的消息进行检查,而无 法检查出发送者的身份是否被 Mallory 进行了伪装。也就是说,单向散列函数能够辨别出 “篡 改”,但无法辨别出 "伪装”。
- 当我们不仅需要确认文件的完整性,同时还需要确认这个文件是否真的属于 Alice 时,仅靠完整性检査是不够的,我们还需要进行认证。 用于认证的技术包括消息验证码和数字签名。消息认证码能够向通信对象保证消息没有被篡改,而数字签名不仅能够向通信对象保证消息没有被篡改,还能够向所有第三方做出这样的 保证。
- 认证需要使用密钥,也就是通过对消息附加 Alice 的密钥(只有 Alice 才知道的秘密信息 ) 来确保消息真的属于 Alice。
数字签名的相关内容,在我这篇博客中一致指向的博客中提到了。因此下边主要提到的是消息认证码技术。
消息认证码
什么事消息认证码
- 消息认证码(Message Authentication Code )是一种确认完整性并进行认证的技术,取三个 单词的首字母,简称为 MAC。
- 消息认证码的输人包括任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为 MAC 值。
- 根据任意长度的消息输出固定长度的数据,这一点和单向散列函数很类似。但是单向散列 函数中计算散列值时不需要密钥,相对地,消息认证码中则需要使用发送者与接收者之间共享 的密钥。
- 要计算 MAC 必须持有共享密钥,没有共享密钥的人就无法计算 MAC 值,消息认证码正是 利用这一性质来完成认证的。此外,和单向散列函数的散列值一样,哪怕消息中发生1比特的 变化,MAC 值也会产生变化,消息认证码正是利用这一性质来确认完整性的。当然,消息认证码有很多种实现方法,不过可以暂且这样理解:消息认证码是 一种与密钥相关联的单向散列函数
消息认证码的使用步骤如下:
①发送者与接受者事先共享秘钥。(使用的方法如上述谈到的,可以是公钥密码算法等)
②发送者根据消息计算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 因为仅靠软件无法生成真随机数,因此要加上一个 “伪” 字。
伪随机数生成器的结构如下,伪随机数生成器具有“内部状态”,并根据外部输入的“种子”来生成伪随机数列。
伪随机生成器的具体实现有主要有如下几种
- 杂乱的方法。不推荐
- 线性同余法。该方法不具备不可预测性,因此不能用于密码技术。但是很多伪随机数生成器的库函数都是采用该方法编写的。例如c语言的库函数rand,以及Java的java.util.Random类等。
- 单向散列函数法。该方法中,单向散列函数的单向性是支撑伪随机数生成器不可预测的基础。
- 密码法。密码的机密性是支撑伪随机数生成器不可预测性的基础。
密码技术与实现社会
密码技术小结
6中基本的密码技术
- 对称密码是一种用相同的密钥进行加密和解密的技术,用于确保消息的机密性。在对称密 码的算法方面,目前主要使用的是 AES。尽管对称密码能够确保消息的机密性,但需要解决将 解密密钥配送给接收者的密钥配送问题。
- 公钥密码是一种用不同的密钥进行加密和解密的技术,和对称密码一样用于确保消息的机 密性。使用最广泛的一种公钥密码算法是 RSA, 除此之外还有 ElGamal 和 Rabin 等算法,以及 与其相关 Diffie-Hellman 密钥交换(DH )和椭圆曲线 Dffie-Hellman 密钥交换(ECDH )等技术。 和对称密码相比,公钥密码的速度非常慢,因此一般都会和对称密码一起组成混合密码系统来 使用。公钥密码能够解决对称密码中的密钥交换问题 , 但存在通过中间人攻击被伪装的风险 , 因此需要对带有数字签名的公钥迸行认证。
- 单向散列函数是一种将长消息转换为短散列值的技术,用于确保消息的完整性。在单向散 列函数的算法方面,SHA-1曾被广泛使用,但由于人们已经发现了一些针对该算法的理论上可 行的攻击方式,因此该算法不应再被用于新的用途。今后我们应该主要使用的算法包括目前已 经在广泛使用的SHA-2(SHA-224、SHA-256、SHA-384、SHA-512),以及具有全新结构的 SHA-3 ( Keccak )算法。单向散列函数可以单独使用,也可以作为消息认证码、数字签名以及 伪随机数生成器等技术的组成元素来使用。
- 消息认证码是一种能够识别通信对象发送的消息是否被篡改的认证技术,用于验证消息的完整性,以及对消息进行认证。消息认证码的算法中,最常用的是利用单向散列函数的 HMAC。HMAC 的构成不依赖于某一种具体的单向散列函数算法。消息认证码能够对通信对象 进行认证,但无法对第三方进行认证。此外,它也无法防止否认。消息认证码也可以用来实现 认证加密。
- 数字签名是一种能够对第三方进行消息认证,并能够防止通信对象做出否认的认证技术。 数字签名的算法包括 RSA、ElGamal、DSA、椭圆曲线 DSA ( ECDSA )、爱德华兹曲线 DSA( EDDSA)等。公钥基础设施(PKI)中使用的证书,就是对公钥加上认证机构的数字签名所构成的。要验证公钥的数字签名,需要通过某种途径获取认证机构自身的合法公钥。
- 伪随机数生成器是一种能够生成具备不可预测性的比特序列的技术,由密码和单向散列函数等技术构成。伪随机数生成器用于生成密钥、初始化向量和 nonce 等。
如下图
密码技术与压缩技术
如下图
无论是对称密码还是公钥密码,密码的作用都是确保机密性。由于确保较长的明文整体的 机密性很困难,因此我们用密码将明文转换成密文。这样一来,我们就不必保护明文本身了。 相对地,我们则需要保护加密时所使用的密钥。通过保护较短的密钥来保护较长的明文,这样 的做法可以称为机密性的压缩。
单向散列函数是用于确认完整性的。我们不必检查较长的明文的完整性,只要检查散列值 就能够确认完整性了。通过检查较短的散列值来确认较长的明文的完整性,这样的做法可以称为完整性的压缩。
消息认证码和数字签名都是用于认证的技术 , 但我们并不是直接对较长的消息本身进行认 证, 而是通过将较长的消息与密钥结合起来,生成较短的比特序列(认证符号 ),再通过认证符 号进行认证。在消息认证码中,MAC 值就是认证符号;而在数字签名中,签名就是认证符号。 通过较短的认证符号来对较长的消息进行认证,这样的做法可以称为认证的压缩。
那么伪随机数生成器又是怎样的呢?在伪随机数生成器中,所生成数列的不可预测性是非常重要的。要大量生成具备不可预测性的随机数列非常困难,于是我们通过将种子输人伪随机数生成器,生成具备不可预测性的伪随机数列。也就是说,为了对伪随机数列赋予不可预测性,我们使用了随机数种子,这可以称为不可预测性的压缩。反过来说,伪随机数生成器是将种子所具备的不可预测性进行了扩张。
这里的观点很重要,因此我们从另一个角度来总结一下。
• 密钥是机密性的精华
• 散列值是完整性的精华
• 认证符号(MAC值和签名)是认证的精华
• 种子是不可预测性的精华
如下表
比特币
比特币之 所以能够成为一种流通的货币,完全依赖于全世界所有比特币用户组成的 P2P 网络 ( Peer to Peer Network)。也就是说,全世界所有比特币用户的计算机(node或者peer)共同保存、验证 和使用支撑比特币体系的所有必要信息。
与其说比特币是一种货币,不如说比特币是一种基于 P2P 网络的支付结算系统,这样更易 于人们理解其本质。比特币用户通过使用比特币这一支付结算系统实现了价值的转移,因此比 特币看上去才具备了货币的特征。
- 比特币交易是在比特币地址之间完成的。流程如下:①商店生成地址B;②商店将地址B告诉购买者;③购买者生成地址A;④购买者从地址A向地址B支付贷款。比特币中使用的地址是由公钥的散列值生成的。
区块链
区块链就是保存比特币全部交易记录的公共账簿。全世界使用比特币进行的所有交易被记录在一本公共账簿中。顾名思义,区块链即使将交易以区块为单位组织起来的。
区块的添加。比特币的首付款是以交易为单位来进行的,若干条交易会合并为一个区块,并被添加到区块链中。当P2P网络确认区块的添加后,相应的交易也就成立了。如下图:
1. 一个区块是由若干条交易以及一个区块头所组成的,区块头中保存了 “上一个区块的区块 头的散列值”。以图 15-4 中的区块 2 为例,其中区块头 2 中保存的散列值 H2 就是根据它前面的 区块 1 的区块头 1 计算出来的。
2. 此外,区块头中还保存着 “本区块所有交易的整体散列值” 例如,区块头2中的散列值 T2 就是根据区块 2 中记录的所有交易数据计算出的散列值。
3. 区块头中还保存着一个名为 nonce 的任意数值,以及时间戳(图中省略 )等信息。
4. 假设区块 2 中记录的某一条交易中的 1 个比特被修改,那么散列值 T2 就需要重新计算,这 样一来区块头2的内容就会发生变化,因此区块头3中的散列值H3也需要重新计算。也就是 说,一旦对区块链中的数据进行任何改动,都需要重建所改动的区块之后的所有区块的数据。 由此可见,区块头中的两个散列值有效增加了篡改区块链数据的难度。
挖矿
交易成立的前提是一方必须拥有一定量的比特币。那么比特币是如何拥有的呢?
- 随着全世界的比特币交易不断增加,区块链也会随之不断增长,这就意味着 P2P 网络中的“某个人” 在负责将新的区块添加到区块链。有趣的是,“将新的区块添加到区块链” 这一行为,正好就相当于 “创造新的比特币余额”。向区块链中添加区块就好像从金矿中挖出比特币一样, 因此称为挖矿( mining ),而从事挖矿的人则称为矿工(miner )。
- 由于区块链是一条单链,因此在某个特定的时间点只能向其中添加一个区块。按照比特币 协议的规定,成功将区块添加到区块链的矿工将获得挖矿奖励(reward )以及该区块所有交易的 手续费(transactionfee)。2015年,每个区块的挖矿奖励25BTC(约75万日元)
- 为了防止比特币被伪造,矿工必须证明自己确实完成了规定量的工作,这种证明称为工作 量证明( Proof of Work, PoW )。工作量证明是通过散列值来实现的。
- 要向区块链添加新的区块,矿工需要生成合法的区块头,而且区块头中 “前一区块的散列 值” 的格式是有规定的,它的前面若干个比特必须为0。例如,如下的散列值H2可能是下面这样的值。
000000000000000007780B6F7817C431309EDED44F51223352D86A4436023913
- 区块头中之所以需要一个称为 nonce 的任意数值,就是为了凑出像上面这样前面若干比特 都是0的散列值。也就是说,矿工需要不断更换 nonce 进行尝试,直到计算出符合要求的散列值为止。
- 这个过程实际上和暴力破解单向散列函数十分相似。当然,这只是为了证明某个矿工确实 投人了大量的计算资源来完成工作,而并不是真的为了去攻击单向散列函数。比特币系统中大 约每10分钟会添加一个新的区块,为了保持这样的恒定速率,计算的难度(即所需的0的个数 )会不断地被调整。