Python实现AES算法
密码学课程老师留的作业,我觉得用python实现更简单,就用python写了一个加解密的程序。
程序分成三个部分,一个部分是生成轮密钥,一个加密,一个是解密。
生成轮密钥
这个部分要看是不是四的倍数,非四的倍数是简单的,直接异或就可以了。如果是4的倍数,这时就需要执行字节代替和异或运算。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for i in range ( 4 ): #把16进制转成十进制 for j in range ( 0 , 8 , 2 ): self .subkey[i].append( '0x' + key[i * 8 + j:i * 8 + j + 2 ]) for i in range ( 4 , 44 ): #生成密钥 if i % 4 ! = 0 : tmp = xor_32( self .subkey[i - 1 ], self .subkey[i - 4 ]) self .subkey.append(tmp) else : #4的倍数的时候执行 tmp1 = self .subkey[i - 1 ][ 1 :] tmp1.append( self .subkey[i - 1 ][ 0 ]) tmp1 = self .S_box(tmp1) #字节代替 tmp1 = xor_32(tmp1, self .Rcon[i / 4 ]) #和Rcon异或 self .subkey.append(xor_32(tmp1, self .subkey[i - 4 ])) |
加密
加密时最难实现的是列混淆,因为要实现域上的乘法,没想到用递归实现的好方法,还是把一个一个用if判断来进行运算。
解密
解密的时候最难的仍然是逆列混淆运算,仍然是最傻的if判断。
完整代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
# -*- coding: utf-8 -*- """ Created on Fri Nov 1 18:47:24 2019 @author: pkill """ class AesCryption: s_box = { #字节替换s盒 0 :[ '0x63' , '0x7c' , '0x77' , '0x7b' , '0xf2' , '0x6b' , '0x6f' , '0xc5' , '0x30' , '0x01' , '0x67' , '0x2b' , '0xfe' , '0xd7' , '0xab' , '0x76' ], 1 :[ '0xca' , '0x82' , '0xc9' , '0x7d' , '0xfa' , '0x59' , '0x47' , '0xf0' , '0xad' , '0xd4' , '0xa2' , '0xaf' , '0x9c' , '0xa4' , '0x72' , '0xc0' ], 2 :[ '0xb7' , '0xfd' , '0x93' , '0x26' , '0x36' , '0x3f' , '0xf7' , '0xcc' , '0x34' , '0xa5' , '0xe5' , '0xf1' , '0x71' , '0xd8' , '0x31' , '0x15' ], 3 :[ '0x04' , '0xc7' , '0x23' , '0xc3' , '0x18' , '0x96' , '0x05' , '0x9a' , '0x07' , '0x12' , '0x80' , '0xe2' , '0xeb' , '0x27' , '0xb2' , '0x75' ], 4 :[ '0x09' , '0x83' , '0x2c' , '0x1a' , '0x1b' , '0x6e' , '0x5a' , '0xa0' , '0x52' , '0x3b' , '0xd6' , '0xb3' , '0x29' , '0xe3' , '0x2f' , '0x84' ], 5 :[ '0x53' , '0xd1' , '0x00' , '0xed' , '0x20' , '0xfc' , '0xb1' , '0x5b' , '0x6a' , '0xcb' , '0xbe' , '0x39' , '0x4a' , '0x4c' , '0x58' , '0xcf' ], 6 :[ '0xd0' , '0xef' , '0xaa' , '0xfb' , '0x43' , '0x4d' , '0x33' , '0x85' , '0x45' , '0xf9' , '0x02' , '0x7f' , '0x50' , '0x3c' , '0x9f' , '0xa8' ], 7 :[ '0x51' , '0xa3' , '0x40' , '0x8f' , '0x92' , '0x9d' , '0x38' , '0xf5' , '0xbc' , '0xb6' , '0xda' , '0x21' , '0x10' , '0xff' , '0xf3' , '0xd2' ], 8 :[ '0xcd' , '0x0c' , '0x13' , '0xec' , '0x5f' , '0x97' , '0x44' , '0x17' , '0xc4' , '0xa7' , '0x7e' , '0x3d' , '0x64' , '0x5d' , '0x19' , '0x73' ], 9 :[ '0x60' , '0x81' , '0x4f' , '0xdc' , '0x22' , '0x2a' , '0x90' , '0x88' , '0x46' , '0xee' , '0xb8' , '0x14' , '0xde' , '0x5e' , '0x0b' , '0xdb' ], 10 :[ '0xe0' , '0x32' , '0x3a' , '0x0a' , '0x49' , '0x06' , '0x24' , '0x5c' , '0xc2' , '0xd3' , '0xac' , '0x62' , '0x91' , '0x95' , '0xe4' , '0x79' ], 11 :[ '0xe7' , '0xc8' , '0x37' , '0x6d' , '0x8d' , '0xd5' , '0x4e' , '0xa9' , '0x6c' , '0x56' , '0xf4' , '0xea' , '0x65' , '0x7a' , '0xae' , '0x08' ], 12 :[ '0xba' , '0x78' , '0x25' , '0x2e' , '0x1c' , '0xa6' , '0xb4' , '0xc6' , '0xe8' , '0xdd' , '0x74' , '0x1f' , '0x4b' , '0xbd' , '0x8b' , '0x8a' ], 13 :[ '0x70' , '0x3e' , '0xb5' , '0x66' , '0x48' , '0x03' , '0xf6' , '0x0e' , '0x61' , '0x35' , '0x57' , '0xb9' , '0x86' , '0xc1' , '0x1d' , '0x9e' ], 14 :[ '0xe1' , '0xf8' , '0x98' , '0x11' , '0x69' , '0xd9' , '0x8e' , '0x94' , '0x9b' , '0x1e' , '0x87' , '0xe9' , '0xce' , '0x55' , '0x28' , '0xdf' ], 15 :[ '0x8c' , '0xa1' , '0x89' , '0x0d' , '0xbf' , '0xe6' , '0x42' , '0x68' , '0x41' , '0x99' , '0x2d' , '0x0f' , '0xb0' , '0x54' , '0xbb' , '0x16' ] } s_1_box = { #逆字节替换s盒 0 :[ '0x52' , '0x09' , '0x6a' , '0xd5' , '0x30' , '0x36' , '0xa5' , '0x38' , '0xbf' , '0x40' , '0xa3' , '0x9e' , '0x81' , '0xf3' , '0xd7' , '0xfb' ], 1 :[ '0x7c' , '0xe3' , '0x39' , '0x82' , '0x9b' , '0x2f' , '0xff' , '0x87' , '0x34' , '0x8e' , '0x43' , '0x44' , '0xc4' , '0xde' , '0xe9' , '0xcb' ], 2 :[ '0x54' , '0x7b' , '0x94' , '0x32' , '0xa6' , '0xc2' , '0x23' , '0x3d' , '0xee' , '0x4c' , '0x95' , '0x0b' , '0x42' , '0xfa' , '0xc3' , '0x4e' ], 3 :[ '0x08' , '0x2e' , '0xa1' , '0x66' , '0x28' , '0xd9' , '0x24' , '0xb2' , '0x76' , '0x5b' , '0xa2' , '0x49' , '0x6d' , '0x8b' , '0xd1' , '0x25' ], 4 :[ '0x72' , '0xf8' , '0xf6' , '0x64' , '0x86' , '0x68' , '0x98' , '0x16' , '0xd4' , '0xa4' , '0x5c' , '0xcc' , '0x5d' , '0x65' , '0xb6' , '0x92' ], 5 :[ '0x6c' , '0x70' , '0x48' , '0x50' , '0xfd' , '0xed' , '0xb9' , '0xda' , '0x5e' , '0x15' , '0x46' , '0x57' , '0xa7' , '0x8d' , '0x9d' , '0x84' ], 6 :[ '0x90' , '0xd8' , '0xab' , '0x00' , '0x8c' , '0xbc' , '0xd3' , '0x0a' , '0xf7' , '0xe4' , '0x58' , '0x05' , '0xb8' , '0xb3' , '0x45' , '0x06' ], 7 :[ '0xd0' , '0x2c' , '0x1e' , '0x8f' , '0xca' , '0x3f' , '0x0f' , '0x02' , '0xc1' , '0xaf' , '0xbd' , '0x03' , '0x01' , '0x13' , '0x8a' , '0x6b' ], 8 :[ '0x3a' , '0x91' , '0x11' , '0x41' , '0x4f' , '0x67' , '0xdc' , '0xea' , '0x97' , '0xf2' , '0xcf' , '0xce' , '0xf0' , '0xb4' , '0xe6' , '0x73' ], 9 :[ '0x96' , '0xac' , '0x74' , '0x22' , '0xe7' , '0xad' , '0x35' , '0x85' , '0xe2' , '0xf9' , '0x37' , '0xe8' , '0x1c' , '0x75' , '0xdf' , '0x6e' ], 10 :[ '0x47' , '0xf1' , '0x1a' , '0x71' , '0x1d' , '0x29' , '0xc5' , '0x89' , '0x6f' , '0xb7' , '0x62' , '0x0e' , '0xaa' , '0x18' , '0xbe' , '0x1b' ], 11 :[ '0xfc' , '0x56' , '0x3e' , '0x4b' , '0xc6' , '0xd2' , '0x79' , '0x20' , '0x9a' , '0xdb' , '0xc0' , '0xfe' , '0x78' , '0xcd' , '0x5a' , '0xf4' ], 12 :[ '0x1f' , '0xdd' , '0xa8' , '0x33' , '0x88' , '0x07' , '0xc7' , '0x31' , '0xb1' , '0x12' , '0x10' , '0x59' , '0x27' , '0x80' , '0xec' , '0x5f' ], 13 :[ '0x60' , '0x51' , '0x7f' , '0xa9' , '0x19' , '0xb5' , '0x4a' , '0x0d' , '0x2d' , '0xe5' , '0x7a' , '0x9f' , '0x93' , '0xc9' , '0x9c' , '0xef' ], 14 :[ '0xa0' , '0xe0' , '0x3b' , '0x4d' , '0xae' , '0x2a' , '0xf5' , '0xb0' , '0xc8' , '0xeb' , '0xbb' , '0x3c' , '0x83' , '0x53' , '0x99' , '0x61' ], 15 :[ '0x17' , '0x2b' , '0x04' , '0x7e' , '0xba' , '0x77' , '0xd6' , '0x26' , '0xe1' , '0x69' , '0x14' , '0x63' , '0x55' , '0x21' , '0x0c' , '0x7d' ] } Rcon = { #Rcon生成密钥的表 1 : [ '0x01' , '0x00' , '0x00' , '0x00' ], 2 : [ '0x02' , '0x00' , '0x00' , '0x00' ], 3 : [ '0x04' , '0x00' , '0x00' , '0x00' ], 4 : [ '0x08' , '0x00' , '0x00' , '0x00' ], 5 : [ '0x10' , '0x00' , '0x00' , '0x00' ], 6 : [ '0x20' , '0x00' , '0x00' , '0x00' ], 7 : [ '0x40' , '0x00' , '0x00' , '0x00' ], 8 : [ '0x80' , '0x00' , '0x00' , '0x00' ], 9 : [ '0x1B' , '0x00' , '0x00' , '0x00' ], 10 : [ '0x36' , '0x00' , '0x00' , '0x00' ] } Matrix = [ #列混淆 [ '0x02' , '0x03' , '0x01' , '0x01' ], [ '0x01' , '0x02' , '0x03' , '0x01' ], [ '0x01' , '0x01' , '0x02' , '0x03' ], [ '0x03' , '0x01' , '0x01' , '0x02' ] ] InvMatrix = [ #逆列混淆 [ '0x0e' , '0x0b' , '0x0d' , '0x09' ], [ '0x09' , '0x0e' , '0x0b' , '0x0d' ], [ '0x0d' , '0x09' , '0x0e' , '0x0b' ], [ '0x0b' , '0x0d' , '0x09' , '0x0e' ] ] plaintext = [[],[],[],[]] #存放明文 plaintext1 = [[],[],[],[]] subkey = [[],[],[],[]] #存放密钥 def __init__( self ,key): #构造函数,同时生成密钥 for i in range ( 4 ): #把16进制转成十进制 for j in range ( 0 , 8 , 2 ): self .subkey[i].append( '0x' + key[i * 8 + j:i * 8 + j + 2 ]) for i in range ( 4 , 44 ): #生成密钥 if i % 4 ! = 0 : tmp = xor_32( self .subkey[i - 1 ], self .subkey[i - 4 ]) self .subkey.append(tmp) else : #4的倍数的时候执行 tmp1 = self .subkey[i - 1 ][ 1 :] tmp1.append( self .subkey[i - 1 ][ 0 ]) tmp1 = self .S_box(tmp1) #字节代替 tmp1 = xor_32(tmp1, self .Rcon[i / 4 ]) #和Rcon异或 self .subkey.append(xor_32(tmp1, self .subkey[i - 4 ])) def AddRoundKey( self , round ): #轮密钥加函数 for i in range ( 4 ): self .plaintext[i] = xor_32( self .plaintext[i], self .subkey[ round * 4 + i]) def PlainSubBytes( self ): #明文字节代替函数 for i in range ( 4 ): self .plaintext[i] = self .S_box( self .plaintext[i]) def ShiftRows( self ): #移位函数 p1,p2,p3,p4 = self .plaintext[ 0 ][ 1 ], self .plaintext[ 1 ][ 1 ], self .plaintext[ 2 ][ 1 ], self .plaintext[ 3 ][ 1 ] self .plaintext[ 0 ][ 1 ] = p2; self .plaintext[ 1 ][ 1 ] = p3; self .plaintext[ 2 ][ 1 ] = p4; self .plaintext[ 3 ][ 1 ] = p1 p1,p2,p3,p4 = self .plaintext[ 0 ][ 2 ], self .plaintext[ 1 ][ 2 ], self .plaintext[ 2 ][ 2 ], self .plaintext[ 3 ][ 2 ] self .plaintext[ 0 ][ 2 ] = p3; self .plaintext[ 1 ][ 2 ] = p4; self .plaintext[ 2 ][ 2 ] = p1; self .plaintext[ 3 ][ 2 ] = p2 p1,p2,p3,p4 = self .plaintext[ 0 ][ 3 ], self .plaintext[ 1 ][ 3 ], self .plaintext[ 2 ][ 3 ], self .plaintext[ 3 ][ 3 ] self .plaintext[ 0 ][ 3 ] = p4; self .plaintext[ 1 ][ 3 ] = p1; self .plaintext[ 2 ][ 3 ] = p2; self .plaintext[ 3 ][ 3 ] = p3 def S_box( self ,row): #s盒函数 a = [] for i in range ( 4 ): a.append( self .s_box[ int (row[i][ 2 ], 16 )][ int (row[i][ 3 ], 16 )]) return a def S_1_box( self ,row): #逆s盒函数 a = [] for i in range ( 4 ): a.append( self .s_1_box[ int (row[i][ 2 ], 16 )][ int (row[i][ 3 ], 16 )]) return a def MixColumns( self ): #列混淆函数 for i in range ( 4 ): for j in range ( 4 ): self .plaintext1[i].append(mc( self .Matrix[j], self .plaintext[i])) def InvShiftRows( self ): #逆移位函数 p1,p2,p3,p4 = self .plaintext[ 0 ][ 1 ], self .plaintext[ 1 ][ 1 ], self .plaintext[ 2 ][ 1 ], self .plaintext[ 3 ][ 1 ] self .plaintext[ 3 ][ 1 ] = p3; self .plaintext[ 2 ][ 1 ] = p2; self .plaintext[ 0 ][ 1 ] = p4; self .plaintext[ 1 ][ 1 ] = p1 p1,p2,p3,p4 = self .plaintext[ 0 ][ 2 ], self .plaintext[ 1 ][ 2 ], self .plaintext[ 2 ][ 2 ], self .plaintext[ 3 ][ 2 ] self .plaintext[ 0 ][ 2 ] = p3; self .plaintext[ 1 ][ 2 ] = p4; self .plaintext[ 2 ][ 2 ] = p1; self .plaintext[ 3 ][ 2 ] = p2 p1,p2,p3,p4 = self .plaintext[ 0 ][ 3 ], self .plaintext[ 1 ][ 3 ], self .plaintext[ 2 ][ 3 ], self .plaintext[ 3 ][ 3 ] self .plaintext[ 0 ][ 3 ] = p2; self .plaintext[ 1 ][ 3 ] = p3; self .plaintext[ 2 ][ 3 ] = p4; self .plaintext[ 3 ][ 3 ] = p1 def InvSubBytes( self ): #逆字节代替 for i in range ( 4 ): self .plaintext[i] = self .S_1_box( self .plaintext[i]) def InvMixColumns( self ): #逆列混淆 for i in range ( 4 ): for j in range ( 4 ): self .plaintext1[i].append(mc( self .InvMatrix[j], self .plaintext[i])) def AesEncrypt( self ,plain): #加密函数 for i in range ( 4 ): for j in range ( 0 , 8 , 2 ): self .plaintext[i].append( '0x' + plain[i * 8 + j:i * 8 + j + 2 ]) #把16进制转化成二进制 self .AddRoundKey( 0 ) #第一轮密钥加 for i in range ( 9 ): self .PlainSubBytes() #字节代替 self .ShiftRows() #行移位 self .MixColumns() #列混淆 self .plaintext = self .plaintext1 #把列混淆生成的密钥赋值给plaintext self .plaintext1 = [[],[],[],[]] #重置 self .AddRoundKey(i + 1 ) self .PlainSubBytes() #最后一轮字节代替 self .ShiftRows() #最后一轮行移位 self .AddRoundKey( 10 ) #最后一轮轮密钥加 return Matrixtostr( self .plaintext) #把二进制转换成诗十六进制 def AesDecrypt( self ,cipher): for i in range ( 4 ): for j in range ( 0 , 8 , 2 ): self .plaintext[i].append( '0x' + cipher[i * 8 + j:i * 8 + j + 2 ]) #16进制转成2进制 self .AddRoundKey( 10 ) #轮密钥加 for i in range ( 9 ): self .InvShiftRows() #逆行移位 self .InvSubBytes() #逆字节代替 self .AddRoundKey( 9 - i) #轮密钥加 self .InvMixColumns() #逆列混淆 self .plaintext = self .plaintext1 self .plaintext1 = [[],[],[],[]] self .InvShiftRows() self .InvSubBytes() self .AddRoundKey( 0 ) return Matrixtostr( self .plaintext) #把二进制转换成十六进制 def hextobin(word): #把十六进制转换成二进制 word = bin ( int (word, 16 ))[ 2 :] for i in range ( 0 , 8 - len (word)): #补全八位 word = '0' + word return word def bintohex(word): #把二进制转换十六进制 word = hex ( int (word, 2 )) if len (word) = = 4 : return word elif len (word) < 4 : return word.replace( 'x' , 'x0' ) #0x5-->0x05 def xor_32(start, end): #32位进行异或 a = [] for i in range ( 0 , 4 ): xor_tmp = "" b = hextobin(start[i]) c = hextobin(end[i]) for j in range ( 8 ): xor_tmp + = str ( int (b[j], 10 )^ int (c[j], 10 )) a.append(bintohex(xor_tmp)) return a def xor_8(begin, end): #8位异或 xor_8_tmp = "" for i in range ( 8 ): xor_8_tmp + = str ( int (begin[i])^ int (end[i])) return xor_8_tmp def Fa(a,b): #列混淆中的乘法运算 if a = = 1 : return b elif a = = 2 : if b[ 0 ] = = '0' : b = b[ 1 :] + '0' else : b = b[ 1 :] + '0' b = xor_8(b, '00011011' ) return b elif a = = 3 : tmp_b = b if b[ 0 ] = = '0' : b = b[ 1 :] + '0' else : b = b[ 1 :] + '0' b = xor_8(b, '00011011' ) return xor_8(b,tmp_b) elif a = = 9 : tmp_b = b return xor_8(tmp_b,Fa( 2 ,Fa( 2 ,Fa( 2 ,b)))) elif a = = 11 : tmp_b = b return xor_8(tmp_b, xor_8(Fa( 2 ,Fa( 2 ,Fa( 2 ,b))),Fa( 2 ,b))) elif a = = 13 : tmp_b = b return xor_8(tmp_b, xor_8(Fa( 2 ,Fa( 2 ,Fa( 2 ,b))),Fa( 2 ,Fa( 2 ,b)))) elif a = = 14 : return xor_8(Fa( 2 ,b), xor_8(Fa( 2 ,Fa( 2 ,Fa( 2 ,b))),Fa( 2 ,Fa( 2 ,b)))) def mc(s1,s2): #列混淆中的矩阵乘法 result = [] s3 = [] for i in range ( 4 ): s3.append(hextobin(s2[i])) for i in range ( 4 ): result.append(Fa( int (s1[i], 16 ),s3[i])) for i in range ( 3 ): result[ 0 ] = xor_8(result[ 0 ],result[i + 1 ]) return bintohex(result[ 0 ]) def Matrixtostr(matrix): #矩阵转成字符串 result = "" for i in range ( 4 ): for j in range ( 4 ): result + = matrix[i][j][ 2 :] return result |
测试
输入和输出都是16进制格式的字符串:
测试例子:
key = 2b7e151628aed2a6abf7158809cf4f3c
plain = 3243f6a8885a308d313198a2e0370734
cipher = 3925841d02dc09fbdc118597196a0b32
测试程序
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# -*- coding: utf-8 -*- """ Created on Fri Nov 1 19:37:00 2019 @author: whoami """ from AesCryption import AesCryption key = input ( "key = " ) plain = input ( "plain = " ) cipher = input ( "cipher = " ) aesencrypt = AesCryption(key) print ( '密文是:' + aesencrypt.AesEncrypt(plain)) print () print ( '明文是:' + aesencrypt.AesDecrypt(cipher)) |
Python实现AES-CFB8加解密
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import json from base64 import b64encode, b64decode from Crypto.Cipher import AES from Crypto.Random import get_random_bytes def cfb_encrypt(data, key, iv = None ): if iv is None : iv = get_random_bytes( 16 ) cipher = AES.new(key, AES.MODE_CFB, iv, segment_size = 8 ) ct_bytes = cipher.encrypt(data) ct = b64encode(ct_bytes).decode( 'utf-8' ) iv = b64encode(iv).decode( 'utf-8' ) return encrypt_data, iv def cfb8_decrypt(ciphertext, iv, key): iv = b64decode(iv) ct = b64decode(ciphertext) cipher = AES.new(key, AES.MODE_CFB, iv, segment_size = 8 ) decrypt_data = cipher.decrypt(ct) return decrypt_data |
以上就是python实现AES算法及AES-CFB8加解密源码的详细内容,更多关于Python实现AES-CFB8加解密算法的资料请关注服务器之家其它相关文章!
原文链接:https://blog.csdn.net/lwuis_/article/details/102885002