【信息保护论】Ch11. 密钥和随机数
密钥Diffie-Hellman 密钥交换PBE(password based encryption)
随机数真随机数伪随机数对PRNG的攻击
密钥
key是密码学与信息安全中最重要的组成部分之一。那么具体的说,key到底是什么呢?
密钥是一个非常大的数,密钥除了本身数值很大之外,更重要的是密钥空间也非常大。密钥空间的大小由密钥比特的长度决定。
在不同加密技术中,密钥的长度也大抵不同。
-表现二进制01010001 11101100 01001011 00010010 00111101 01000010 0000001116进制51 EC 4B 12 3D 42 03十进制230592802862699551024bit十六进制
密钥与明文具有相同的价值。对于黑客而言,拿到密钥与拿到明文无差异。加密算法本身并不一定要保密,因为很多加密算法具有强单方向性,应当使用被鉴证后的加密技术,通过把密钥保存作为保密手段来维持密码机密性。Session key:临时密钥。每次通讯时生成新的,使用完毕后销毁并不再出现该密钥,由于生成随机数大多由软件完成,而软件又不能生成真正的随机数,伪随机数生成器只能通过算法保证在较长时间内不重复,但是必然有一个时刻会进入一个循环。master key:反复使用的密钥,也就是一般需要我们妥善保管的密钥。CEK(contents encrypting key):用于加密明文的密钥。KEK(key encrypting key):用于加密密钥的密钥,如KDC和CA中的可信赖公钥配送。
密钥的阶段解析生成阶段使用(伪)随机数生成器生成。硬件生成的随机数是真随机数,软件生成的随机数是伪随机数。使用的伪随机数生成器也要有[不可预测性],必须使用被认证过的加密用随机数生成器,像C/Java编译器自带的随机函数是不可取的,那些函数使用了非常简单的矩阵随机,在密码学领域应用强度不够。生成阶段2一般需要使用password或passphrase生成,把这些较长且复杂的只有自己知道意义的明文通过单方向哈希函数,用他们的哈希值当做密钥。之前提到的PBE就是这里的一种变式,通过附加salt并计算哈希值来当做密钥。配送阶段事前共享、KDC、公钥加密、Diffie-Hellman更新阶段一般密钥使用一段时间或者频度后,需要进行更新。最简单的密钥更新就是将当前密钥通过哈希函数,生成的哈希值作为下一个密钥使用。这样即便密钥泄露,也能防止过去的信息被解密。保存阶段①记住密钥②保存到文件/记事本,并将文件保存到安全场所(保险箱之类的)③加密密钥后再保存 .etcKEKKEK可以保存多个CEK废弃阶段不再使用的密钥要切实删除。如果密钥遗失或被盗窃,则要发出废弃密钥的申请。
Diffie-Hellman 密钥交换
Ipsec现在也在使用该算法的改良版本。之前提到密钥配送问题时,简单的提了一下,这里讲一下具体流程。
Alice传送给Bob两个素数P和G。Alice生成一个随机数A。Bob生成一个随机数B。Alice计算GA mod P;Bob计算 GB mod P,然后二者互换这两个数。KeyAlice= (GB mod P)^A mod P= GB×A mod PKeyBob= (GA mod P)^B mod P= GA×B mod PKeyAlice=KeyBob,使用对称加密开始会话。
在上面这个流程中,可能被窃听的有两个素数G和P,以及两者的计算结果,分别是GB mod P和GA mod P。知道这四个数,要求GA×B mod P是数学上的难解问题。该算法由于难解性,比较安全,要求P尽可能大,这样两方可以选择的伪随机数也会更加随机。
实战演练AliceBob1传输P=13和G=2两个随机数接收P和G两个随机数2A=9B=73GA mod P=219 mod 13=5GB mod P=27 mod 13=114将5这个数给Bob将11这个数给Alice5(GB mod P)A mod P=119 mod 13=8-6-(GA mod P)B mod P=57 mod 13=87KeyAlice=KeyBobKeyAlice=KeyBob
PBE(password based encryption)
PBE加密之前也简单提过,其核心在于赋予password后面的填充随机数salt。因此PBE可以简单概括为三个阶段,分别是KEK生成/Session key生成/加密明文。
KEK生成:使用伪随机数生成器生成salt,salt是一个随机数填充。将salt和人为创造的password按顺序结合并通过单方向哈希函数,该哈希值就作为KEK使用。Session key生成:使用伪随机数生成器生成一个随机数,当做临时密钥,该密钥用KEK加密后与salt一同保存到安全场所。在临时密钥加密完成后,将对应的KEK销毁。只要有password和salt就可以再次生成相同的密钥,因此解密问题无忧。加密明文:用临时密钥加密明文。
解密过程:从安全场所取得Session keyCEK和salt。将salt和password按顺序组合并通过哈希函数计算出KEK,用KEK解密Session keyCEK得到Session key,然后解密密文。
salt的重要性:任何意识载体都存在一定固有的格式,人、语言、定理都是,人必然会受到环境文化生活等诸多方面的影响,那么本身推测password就成为了可能,再利用现在强大的数据分析工具,能够在事前准备大量的password候补,如果不使用salt,则这些password的候补就有极大可能直接破译加密系统。而使用salt后,仅仅拥有password候补就很不充分了,因为salt的组合会对应的生成相当巨大的KEK空间,会大幅增加黑客的操作难度。password的重要性:人脑不足以记忆电脑破解不出来的bit位数的密码,而随机数生成的salt相比生成的session key安全性能要差很多,也就说KEK本身比CEK的安全性要查很多。举个例子就想把坚实的金库保管到脆弱的金库中。CEK一般会保存的IC card中。PBE改善:将salt和password的组合通过N遍哈希函数。提升其混乱程度。password准则:一个password的不要应用多个场景。根据信息价值可以分多层次安全性的password。更换密码时,只更换密码中的一小部分是不可以的。等。但是由于日常生活中人们越来越嫌麻烦,因此如果想要使用安全密码,建议使用伪随机数生成器生成并保存到安全场所。
随机数
之前涉及到的所有知识点基本上都有一个词——随机。没错,一个密码越随机越无序,则越安全。本小节将对随机数进行详细说明。
-密钥生成密钥对生成块加密模式中的初始化向量IV为了防止再传送攻击而添加的noncesaltpadding
随机数的用途:无论多强力的加密算法,只要攻击者知道就丧失了意义,使用随机数制作的密钥,对于攻击者而言是为了起到一定的迷惑作用。如,我用IloveyouForever当做密码,与sa53gf4a3w4t3asd4gz.d4g8W4r383a7r4当做密码,前者一看就能够相信这是明文,而后者则可能还是密文。
随机数的性质:
随机性:统计上没有偏重,完全混乱无序不可预测性:根据之前的随机数无法推断出即将生成的随机数不可再现性:已经出现的随机数不会从该随机数生成器中第二次出现,想要再现该随机数,除了在生成时保存该随机数别无他法。
随
机
性
⊆
不
可
预
测
性
⊆
不
可
再
现
性
随机性\subseteq不可预测性\subseteq不可再现性
随机性⊆不可预测性⊆不可再现性周期性:伪随机数生成器生成的随机数,总有一个时间点会进入重复的下一个循环,只要有周期性,就不是真随机数,不具有不可再现性。
-随机性不可预测性不可再现性备注弱伪随机数生成器○××不可用于加密技术强伪随机数生成器○○×可用于加密技术真随机数生成器○○○可用于加密技术
真随机数
真随机数生成必须使用硬件,仅仅软件绝不可能生成真随机数。由于受制于硬件,因此随机数的生成也受环境因素影响。如
周边温度与声音大小用户鼠标的位置键盘键入时间放射线观测的输出等多种物理环境信息
伪随机数
软件生成,成本相对低廉,有周期性不具备不可再现性。核心是种子SEED。种子直接影响伪随机数生成器(PRNG)的内部状态。
内部状态:
PRNG管理的内存值。PRNG的第一个随机数以其内存值为基础进行计算根据下一个随机数的要求,自身的内部状态也会随之变化。PRNG的算法有两个功能,一个是生成随机数,一个是改变PRNG的内部状态。
种子:本身要保密。是PRNG初始化内部状态的必备元素,本身是一个随机数。
PRNG标准:
长周期:周期短则PRNG本身安全性弱,就不具备不可预测性。简洁算法:比起复杂的算法,明确的算法要更容易评估安全性。程序设计者本身都不能理解的算法生成的随机数很难说安全性如何。线性合同法(linear congruential method):一般最常用的PRNG,尤其是各种编译器。是将现随机数值的-A+C然后除以M,生成下一个随机数。
生成步骤过程1R0=(A×Seed+C) mod N2R1=(A×R0+C) mod MiRi=(A×Ri-1+C) mod M
4, 5, 1, 3, 2, 6, 4, 5, 1, 3, 2, 6, …这种情况下,4, 5, 1, 3, 2, 6这六个数为一个循环,进行无限循环下去。
线性合同法短处:无预测不可能性。不可用于密码应用技术中。C 函数的 rand和Java的 java.util.Random 类都是使用的该算法。因此生成随机数绝对不可以使用编译器自带的随机数方法。
单方向哈希函数:也可以当做PRNG。
随机数使用种子重置计数器使用单向哈希函数将计数器输出为哈希值这个哈希值被当做随机数计数器值+1根据需要重复2~4过程
另一种错误的形式:
随机数使用种子重置计数器使用单向哈希函数将计数器输出为哈希值这个哈希值被当做随机数将这个哈希值作为下一个内部状态根据需要重复2~4过程
为什么是错误的? 因为用前者经过计算得到后者,前者与后者是有关联的,虽然有单方向性,但是却也有着明确的个关联性。不具备不可预测性。
加密实现PRNG:
随机数使用种子重置计数器加密计数器这个密文被当做随机数计数器值+1根据需要重复2~4过程
ANSI X9.17标准步骤重置内部状态1加密当前时刻2内部状态XOR②密文3加密③的结果4将④作为随机数输出5④的输出XOR现在时刻的密文6加密⑥的结果7将⑦的结果当做下一轮的内部状态8根据需要重复步骤②~⑧9
⑥和②的现在时刻是相同的时刻。
对PRNG的攻击
对种子seed的攻击:可以说对于PRNG,seed就是key的作用,只要种子被窃取,则意味着这一个PRNG生成的所有伪随机数都被窃取。真随机数生成器没有这个问题。随机池攻击:PRNG当合法用户需要使用时,会分配对应需求量的随机数,然后这些随机数会被记录到一个类似日志的文件中,称为随机池。这个随机池由于存储了所有可能出现过的伪随机数的出现顺序,即便这个池本身没有什么价值,但是因为存储到里面的伪随机数终有一天会重复,所以这个文件如果被攻击者窃取,则可以对RPNG进行进一步推测。