脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python实现AES算法及AES-CFB8加解密源码

python实现AES算法及AES-CFB8加解密源码

2022-09-18 20:24看到请叫我去学习 Python

这篇文章主要为大家介绍了python实现AES算法及AES-CFB8加解密的源码示例,有需要朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

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

延伸 · 阅读

精彩推荐