必威体育Betway必威体育官网
当前位置:首页 > IT技术

DES算法实例详解

时间:2019-08-28 13:13:13来源:IT技术作者:seo实验室小编阅读:83次「手机版」
 

des

目录

  • 国家标准局催生了DES
  • 一些初步的DES例子
  • DES到底是如何工作
  • 第一步:创建16个子秘钥,每个长48比特
  • 第二步:加密数据的每个64位区块
  • Reference

译自J. Orlin Grabbe的名作《DES Algorithm Illustrated》,国外许多大学将该文章作为补充材料,可作为理解DES算法的最佳入门手册。反观许多教材介绍DES时直接照搬一张流程图,图中IP等缩写符号不加解释,让人误解;许多博客则直接给出蹩脚的源码,对内部流程缺乏解读。事实上,DES在算法上并不复杂,只是流程繁多而已。此时利用一个简单的例子,手工推演一下就能轻松理解。

DES.png

DES (Data Encryption Standard)算法是世界上最常用的加密算法。在很长时间内,许多人心目中“密码生成”与DES一直是个同义词。尽管最近有个叫Electronic Frontier Foundation的组织造了台价值22万的机器尝试破解DES加密的数据,DES和它的变种“三重数据加密算法”仍将在政府和银行中广泛应用(译注:本文年代久远,在2001年AES成为了DES的替代品)。

DES是怎样工作的?本文将通过一个简单的例子来一步步展示DES的加密流程。自DES诞生以来,许多加密算法(修改数据的方法)都采用了类似DES的手段。一旦理解了DES中的变换,你一定能够更轻松地理解这些现代加密算法中的门道。

但在此之前,不妨先了解一下DES的发展历史。

国家标准局催生了DES

1973年5月,在尼克松任期,美国国家标准局下发了红头文件,征求加密算法来保护传输过程中的数据。国家标准局等了很久一直没有人投标,一直到1974年8月6日,尼克松卸任前三天,IBM才拿出了自己家开发的一套代号LUCIFER(金星)的东西。美国安全局评估后,在1977年7月15日采用了LUCIFER的一个变种作为数据加密标准DES。

DES很快被非数字媒体采用,比如电话线中的信号加密。在那些年里,国际香料组织IFF曾用DES来加密那些用电话线传输的秘密配方。(“With Data Encryption, Scents Are Safe at IFF,”Computerworld14, No. 21, 95 (1980))

同时,作为政府之后第二大急需加密的银行业也将DES作为广泛应用的标准,美国国家标准协会ANSI制定了整个银行业的加密规范。1980年采用的ANSI X3.92指定了DES算法的应用。

一些初步的DES例子

DES处理比特,或者说二进制数字。我们知道,每四个比特构成一个十六进制数。DES加密一组64位的信息,也就是16个16进制数。为了完成加密,DES同样使用64位长的密码。但是,秘钥中每8位被忽略掉,这样导致DES中有效的秘钥长度为56位。但是,在任何情况下,每64位一个块是DES永恒的组织方式。

比如,如果我们手上的明文是:

  1. 8787878787878787

选取了DES秘钥:

  1. 0E329232EA6D0D73

我们就能得到密文:

  1. 0000000000000000

如果对上述密文使用相同的DES秘钥

  1. 0E329232EA6D0D73

来解密的话,我们就能得到原来的明文

  1. 8787878787878787

这个例子简单明了,因为我们的明文就是64位长的,明文当然也可以是多个64位那么长。但大部分情况下,现实生活中的明文都不是64位(16个16进制位)的整数倍。

比如,对于这段文本:

  1. Yourlipsaresmootherthanvaseline

它是38字节(76个16进制位)长的。所以在DES加密前,这段文本必须在尾部补充一些额外的字节。一旦密文被解密,这些多余的字节将被丢弃。当然,具体有多种补充的方法。在这里,我们简单地补充0在尾部,使得消息是8字节的整数倍。

这段纯文本在16进制下是:

  1. 596F7572206C6970732061726520736D6F6F74686572207468616E20766173656C696E650D0A

注意这里前72个十六进制数字代表英文,但0D代表回车符,0A代表换行符,代表文本文件的结束。然后我们在这段十六进制码的尾部添加一些0,使其恰好为80个十六进制位:

  1. 596F7572206C6970732061726520736D6F6F74686572207468616E20766173656C696E650D0A0000

如果我们使用相同的秘钥:

  1. 0E329232EA6D0D73

加密这段数据,我们将得到如下密文:

  1. C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D64381909DD52F78F5358499828AC9B453E0E653

这就是可供传输或储存的秘密代码了。解密它就可以得到原文“Your lips are smoother than vaseline”。(设想一下如果克林顿的情妇加密过这些暧昧数据的话,克林顿该是有多庆幸。)

DES到底是如何工作的

DES是一个基于组块的加密算法,这意味着无论输入还是输出都是64位长度的。也就是说DES产生了一种最多264种的变换方法。每个64位的区块被分为2个32位的部分,左半部分L和右半部分R。(这种分割只在特定的操作中进行。)

比如,取明文M为

  1. M=0123456789ABCDEF

这里的M是16进制的,将M写成二进制,我们得到一个64位的区块:

  1. M=0000000100100011010001010110011110001001101010111100110111101111
  2. L=00000001001000110100010101100111
  3. R=10001001101010111100110111101111

M的第一位是0,最后一位是1,我们从左读到右。

DES使用56位的秘钥操作这个64位的区块。秘钥实际上也是储存为64位的,但每8位都没有被用上(也就是第8, 16, 24, 32, 40, 48, 56, 和64位都没有被用上)。但是,我们仍然在接下来的运算中将秘钥标记为从1到64位的64个比特。不过,你也许会看到,刚刚提到的这8个在创建子秘钥的时候会被忽略掉。

举个例子,取十六进制秘钥K为

  1. K=133457799BBCDFF1

我们可以得到它的二进制形式(1为0001,3为0011.依次类推,并且将每八位写成一组。这样每组的最后一位都没有被用上。)

  1. K=0001001100110100010101110111100110011011101111001101111111110001

第一步:创建16个子秘钥,每个长48比特

这个64位的秘钥首先根据表格PC-1进行变换。

  1. PC-1
  2. 5749413325179
  3. 1585042342618
  4. 1025951433527
  5. 1911360524436
  6. 63554739312315
  7. 7625446383022
  8. 1466153453729
  9. 211352820124

由于上表中第一个元素为57,这将使原秘钥的第57位变换为新秘钥K+的第1位。同理,原秘钥的第49位变换为新秘钥的第2位……原秘钥的第4位变换为新秘钥的最后一位。注意原秘钥中只有56位会进入新秘钥,上表也只有56个元素。

比如,对于原秘钥:

  1. K=0001001100110100010101110111100110011011101111001101111111110001

我们将得到56位的新秘钥:

  1. K+=11110000110011001010101011110101010101100110011110001111

然后,将这个秘钥拆分为左右两部分,C0D0,每半边都有28位。

比如,对于新秘钥,我们得到:

  1. C0=1111000011001100101010101111
  2. D0=0101010101100110011110001111

对相同定义的C0D0,我们现在创建16个块CnDn, 1<=n<=16。每一对CnDn都是由前一对Cn-1Dn-1移位而来。具体说来,对于n= 1, 2, …, 16,在前一轮移位的结果上,使用下表进行一些次数的左移操作。什么叫左移?左移指的是将除第一位外的所有位往左移一位,将第一位移动至最后一位。

  1. IterationNumberof
  2. NumberLeftShifts
  3. 11
  4. 21
  5. 32
  6. 42
  7. 52
  8. 62
  9. 72
  10. 82
  11. 91
  12. 102
  13. 112
  14. 122
  15. 132
  16. 142
  17. 152
  18. 161

这意味着,比如说,C3andD3C2andD2移位而来的,具体来说,通过2次左移位;C16andD16则是由C15andD15通过1次左移得到的。在所有情况下,一次左移就是将所有比特往左移动一位,使得移位后的比特的位置相较于变换前成为2, 3,…, 28, 1。

比如,对于原始子秘钥C0andD0,我们得到:

  1. C0=1111000011001100101010101111
  2. D0=0101010101100110011110001111
  3. C1=1110000110011001010101011111
  4. D1=1010101011001100111100011110
  5. C2=1100001100110010101010111111
  6. D2=0101010110011001111000111101
  7. C3=0000110011001010101011111111
  8. D3=0101011001100111100011110101
  9. C4=0011001100101010101111111100
  10. D4=0101100110011110001111010101
  11. C5=1100110010101010111111110000
  12. D5=0110011001111000111101010101
  13. C6=0011001010101011111111000011
  14. D6=1001100111100011110101010101
  15. C7=1100101010101111111100001100
  16. D7=0110011110001111010101010110
  17. C8=0010101010111111110000110011
  18. D8=1001111000111101010101011001
  19. C9=0101010101111111100001100110
  20. D9=0011110001111010101010110011
  21. C10=0101010111111110000110011001
  22. D10=1111000111101010101011001100
  23. C11=0101011111111000011001100101
  24. D11=1100011110101010101100110011
  25. C12=0101111111100001100110010101
  26. D12=0001111010101010110011001111
  27. C13=0111111110000110011001010101
  28. D13=0111101010101011001100111100
  29. C14=1111111000011001100101010101
  30. D14=1110101010101100110011110001
  31. C15=1111100001100110010101010111
  32. D15=1010101010110011001111000111
  33. C16=1111000011001100101010101111
  34. D16=0101010101100110011110001111

我们现在就可以得到第n轮的新秘钥Kn( 1<=n<=16)了。具体做法是,对每对拼合后的子秘钥CnDn,按表PC-2执行变换:

  1. PC-2
  2. 1417112415
  3. 3281562110
  4. 2319124268
  5. 1672720132
  6. 415231374755
  7. 304051453348
  8. 444939563453
  9. 464250362932

每对子秘钥有56位,但PC-2仅仅使用其中的48位。

于是,第n轮的新秘钥Kn的第1位来自组合子秘钥CnDn的第14位,第2位来自第17位,依次类推,知道新秘钥的第48位来自组合秘钥的第32位。

比如,对于第1轮的组合秘钥,我们有:

  1. C1D1=11100001100110010101010111111010101011001100111100011110

通过PC-2的变换后,得到:

  1. K1=000110110000001011101111111111000111000001110010

同理,对于其他秘钥得到:

  1. K2=011110011010111011011001110110111100100111100101
  2. K3=010101011111110010001010010000101100111110011001
  3. K4=011100101010110111010110110110110011010100011101
  4. K5=011111001110110000000111111010110101001110101000
  5. K6=011000111010010100111110010100000111101100101111
  6. K7=111011001000010010110111111101100001100010111100
  7. K8=111101111000101000111010110000010011101111111011
  8. K9=111000001101101111101011111011011110011110000001
  9. K10=101100011111001101000111101110100100011001001111
  10. K11=001000010101111111010011110111101101001110000110
  11. K12=011101010111000111110101100101000110011111101001
  12. K13=100101111100010111010001111110101011101001000001
  13. K14=010111110100001110110111111100101110011100111010
  14. K15=101111111001000110001101001111010011111100001010
  15. K16=110010110011110110001011000011100001011111110101

关于子秘钥的话题就到此为止了,接下来我们看看信息本身。

第二步:加密数据的每个64位区块

对于明文数据M,我们计算一个初始变换IP(Initial permutation)。IP是重新变换数据M的每一位产生的。产生过程由下表决定,表格的下标对应新数据的下标,表格的数值x表示新数据的这一位来自旧数据的第x位。

  1. IP
  2. 585042342618102
  3. 605244362820124
  4. 625446383022146
  5. 645648403224168
  6. 57494133251791
  7. 595143352719113
  8. 615345372921135
  9. 635547393123157

参照上表,M的第58位成为IP的第1位,M的第50位成为IP的第2位,M的第7位成为IP的最后一位。

比如,对M的区块执行初始变换,得到:

  1. M=0000000100100011010001010110011110001001101010111100110111101111
  2. IP=1100110000000000110011001111111111110000101010101111000010101010

这里M的第58位是1,变成了IP的第1位。M的第50位是1,变成了IP的第2位。M的第7位是0,变成了IP的最后一位。

接着讲变换IP分为32位的左半边L0和32位的右半边R0

比如,对于上例,我们得到:

  1. L0=11001100000000001100110011111111
  2. R0=11110000101010101111000010101010

我们接着执行16个迭代,对1<=n<=16,使用一个函数f。函数f输入两个区块——一个32位的数据区块和一个48位的秘钥区块Kn——输出一个32位的区块。定义+表示异或XOR。那么让n从1循环到16,我们计算

Ln=Rn-1

Rn=Ln-1+f(Rn-1,Kn)

这样我们就得到最终区块,也就是n= 16 的L16R16。这个过程说白了就是,我们拿前一个迭代的结果的右边32位作为当前迭代的左边32位。对于当前迭代的右边32位,将它和上一个迭代的f函数的输出执行XOR运算。

比如,对n = 1,我们有:

  1. K1=000110110000001011101111111111000111000001110010
  2. L1=R0=11110000101010101111000010101010
  3. R1=L0+f(R0,K1)

剩下的就是f函数是如何工作的了。为了计算f,我们首先拓展每个Rn-1,将其从32位拓展到48位。这是通过使用一张表来重复Rn-1中的一些位来实现的。我们称这个过程为函数E。也就是说函数E(Rn-1)输入32位输出48位。

定义E为函数E的输出,将其写成8组,每组6位。这些比特是通过选择输入的某些位来产生的,具体选择顺序按下表实现:

  1. EBIT-SELECTIONTABLE
  2. 3212345
  3. 456789
  4. 8910111213
  5. 121314151617
  6. 161718192021
  7. 202122232425
  8. 242526272829
  9. 28293031321

也就是说E(Rn-1)开头的三个比特分别来自Rn-1的第32、1和2位。E(Rn-1) 末尾的2个比特分别来自Rn-1的第32位和第1位。

比如,给定R0,我们可以计算出E(R0):

  1. R0=11110000101010101111000010101010
  2. E(R0)=011110100001010101010101011110100001010101010101

(注意输入的每4位一个分组被拓展为输出的每6位一个分组。)

接着在f函数中,我们对输出E(Rn-1) 和秘钥Kn执行XOR运算:

Kn+E(Rn-1)

比如,对K1,E(R0),我们有:

  1. K1=000110110000001011101111111111000111000001110010
  2. E(R0)=011110100001010101010101011110100001010101010101
  3. K1+E(R0)=011000010001011110111010100001100110010100100111.

到这里我们还没有完成f函数的运算,我们仅仅使用一张表将Rn-1从32位拓展为48位,并且对这个结果和秘钥Kn执行了异或运算。我们现在有了48位的结果,或者说8组6比特数据。我们现在要对每组的6比特执行一些奇怪的操作:我们将它作为一张被称为“S盒”的表格的地址。每组6比特都将给我们一个位于不同S盒中的地址。在那个地址里存放着一个4比特的数字。这个4比特的数字将会替换掉原来的6个比特。最终结果就是,8组6比特的数据被转换为8组4比特(一共32位)的数据。

将上一步的48位的结果写成如下形式:

Kn+E(Rn-1) =B1B2B3B4B5B6B7B8,

每个Bi都是一个6比特的分组,我们现在计算

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)

其中,Si(Bi)指的是第i个S盒的输出。

为了计算每个S函数S1, S2,…, S8,取一个6位的区块作为输入,输出一个4位的区块。决定S1的表格如下:

  1. S1
  2. ColumnNumber
  3. Row
  4. No.0123456789101112131415
  5. 01441312151183106125907
  6. 10157414213110612119538
  7. 24114813621115129731050
  8. 31512824917511314100613

如果S1是定义在这张表上的函数,B是一个6位的块,那么计算S1(B)的方法是:B的第一位和最后一位组合起来的二进制数决定一个介于0和3之间的十进制数(或者二进制00到11之间)。设这个数为i。B的中间4位二进制数代表一个介于0到15之间的十进制数(二进制0000到1111)。设这个数为j。查表找到第i行第j列的那个数,这是一个介于0和15之间的数,并且它是能由一个唯一的4位区块表示的。这个区块就是函数S1输入B得到的输出S1(B)。比如,对输入B= 011011,第一位是0,最后一位是1,决定了行号是01,也就是十进制的1 。中间4位是1101,也就是十进制的13,所以列号是13。查表第1行第13列我们得到数字5。这决定了输出;5是二进制0101,所以输出就是0101。也即S1(011011) = 0101。

同理,定义这8个函数S1,…,S8的表格如下所示:

  1. S1
  2. 1441312151183106125907
  3. 0157414213110612119538
  4. 4114813621115129731050
  5. 1512824917511314100613
  6. S2
  7. 1518146113497213120510
  8. 3134715281412011069115
  9. 0147111041315812693215
  10. 1381013154211671205149
  11. S3
  12. 1009146315511312711428
  13. 1370934610285141211151
  14. 1364981530111212510147
  15. 1101306987415143115212
  16. S4
  17. 7131430691012851112415
  18. 1381156150347212110149
  19. 1069012117131513145284
  20. 3150610113894511127214
  21. S5
  22. 2124171011685315130149
  23. 1411212471315015103986
  24. 4211110137815912563014
  25. 1181271142136150910453
  26. S6
  27. 1211015926801334147511
  28. 1015427129561131401138
  29. 9141552812370410113116
  30. 4321295151011141760813
  31. S7
  32. 4112141508133129751061
  33. 1301174911014351221586
  34. 1411131237141015680592
  35. 6111381410795015142312
  36. S8
  37. 1328461511110931450127
  38. 1151381037412561101492
  39. 7114191214206101315358
  40. 2114741081315129035611

例子:对于第一轮,我们得到这8个S盒的输出:

K1+E(R0) = 011000 010001 011110 111010 100001 100110 010100 100111.

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)= 0101 1100 1000 0010 1011 0101 1001 0111

函数f的最后一步就是对S盒的输出进行一个变换来产生最终值:

f=P(S1(B1)S2(B2)…S8(B8))

变换P由如下表格定义。P输入32位数据,通过下标产生32位输出:

  1. P
  2. 1672021
  3. 29122817
  4. 1152326
  5. 5183110
  6. 282414
  7. 322739
  8. 1913306
  9. 2211425

比如,对于8个S盒的输出:

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)= 0101 1100 1000 0010 1011 0101 1001 0111

我们得到

f= 0010 0011 0100 1010 1010 1001 1011 1011

那么,

R1=L0+f(R0,K1)

= 1100 1100 0000 0000 1100 1100 1111 1111

+ 0010 0011 0100 1010 1010 1001 1011 1011

= 1110 1111 0100 1010 0110 0101 0100 0100

在下一轮迭代中,我们的L2=R1,这就是我们刚刚计算的结果。之后我们必须计算R2=L1+ f(R1, K2),一直完成16个迭代。在第16个迭代之后,我们有了区块L16andR16。接着我们逆转两个区块的顺序得到一个64位的区块:

R16L16

然后对其执行一个最终的变换IP-1,其定义如下表所示:

  1. IP-1
  2. 408481656246432
  3. 397471555236331
  4. 386461454226230
  5. 375451353216129
  6. 364441252206028
  7. 353431151195927
  8. 342421050185826
  9. 33141949175725

也就是说,该变换的的输出的第1位是输入的第40位,第2位是输入的第8位,一直到将输入的第25位作为输出的最后一位。

比如,如果我们使用了上述方法得到了第16轮的左右两个区块:

  1. L16=01000011010000100011001000110100
  2. R16=00001010010011001101100110010101

我们将这两个区块调换位置,然后执行最终变换:

  1. R16L16=0000101001001100110110011001010101000011010000100011001000110100
  2. IP-1=1000010111101000000100110101010000001111000010101011010000000101

写成16进制得到:

  1. 85E813540F0AB405

这就是明文M= 0123456789ABCDEF的加密形式C= 85E813540F0AB405。

解密就是加密的反过程,执行上述步骤,只不过在那16轮迭代中,调转左右子秘钥的位置而已。

Reference

The DES Algorithm Illustrated.pdf

相关阅读

十大滤波算法程序大全:C语言版和arduino版(精心整理)

一、arduino版1、限幅滤波法(又称程序判断滤波法)2、中位值滤波法3、算术平均滤波法4、递推平均滤波法(又称滑动平均滤波法)5、中位值

textteaser算法学习

今天简单来介绍和实现textteaser摘要算法:统计指标:1)句子长度,长度为某个长度的句子为最理想的长度,依照距离这个长度的远近来打分。2

自动排课算法总结

自动排课算法总结 http://blog.csdn.net/Sinde1992/article/details/50321225 零.与遗传算法的比较 遗传的优点: 全局寻优能力强,

简洁明了的克鲁斯卡尔算法求解

小试牛刀–++克鲁斯卡尔算法++ 考研资料书本定义:克鲁斯卡尔算法思想:每次找出侯选边中权值最小的边,就将该边并入生成树中。重复

百度烽火算法升级,持续打击网络劫持问题

网站劫持对用户伤害极大,严重危害搜索用户的网络安全。一直以来,网站劫持问题都是百度搜索重点关注和严厉打击的问题之一。网站劫持

分享到:

栏目导航

推荐阅读

热门阅读