-
2020-12-15 13:54:42
AES加密原理见文章尾部推荐博客
具体代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
import base64
import hashlib
PADDING = '\0'
# 去除填充
def _unpadding(str):
l = len(str)
if l == 0 :
return str
asc = ord(str[-1])
if asc >= 16:
return str
return str[0:-asc]
# 填充
def _padding(data):
length = 16 - (len(data.encode('utf-8')) % 16)
data += chr(length)*length
return data
def _cipher(key):
iv = '0123456789ABCDEF'
m2 = hashlib.md5()
m2.update(key.encode('utf-8'))
return AES.new(key=m2.digest(), mode=AES.MODE_CBC, IV=iv)
class EncryptHelper:
def __init__(self):
pass
@staticmethod
def encrypt(plain_text, key):
data=_cipher(key).encrypt(_padding(plain_text))
return str(base64.b64encode(data),'utf-8')
@staticmethod
def decrypt(encrypted_text, key):
data = base64.b64decode(encrypted_text)
bytes= _cipher(key).decrypt(data)
blank=str(bytes,'utf-8').strip()
return _unpadding(blank)
这里有两个函数解释一下:
chr()函数用一个范围在range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
ord()函数以一个字符(长度为1的字符串)作为参数,返回对应的ASCII数值,或者Unicode数值。
如果所给的Unicode字符超出了你的Python定义范围,则会引发一个TypeError的异常。
更多相关内容 -
python实现AES加密和解密
2020-12-31 17:13:49它是一种对称加密算法,与上一篇博文提到过的RSA非对称算法不同,AES只有一个密钥,这个密钥既用来加密,也用于解密。 AES只是个基本算法,实现AES有几种模式,主要有ECB、CBC、CFB和OFB这几种(其实还有个CTR): 1... -
AES加密算法原理及python实现
2022-03-25 13:25:18AES加密算法原理及python实现AES对称加密算法1.Rijndael的设计思想2.AES的基本结构3.加密解密的详细结构4.四种轮操作1.字节代换(SubBytes)2.行移位操作(线性变换)3.列混合(MixColumn)4.轮密钥加1.密钥编排5.AES...AES加密算法原理及python实现
AES对称加密算法
AES加密算法即密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法(2000年10月2日,比利时密码专家Joan Daemen和Vincent Rijmen提出的Rijindael),是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
1.Rijndael的设计思想
①抵抗所有已知的攻击。
②在多个平台上速度快,编码紧凑。
③设计简单。2.AES的基本结构
AES是一个迭代型分组密码,把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。
AES的处理单位是字节,密钥长度可变,在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。
AES的加密公式为C = E(K,P),在加密函数E中,会执行一个轮函数,并且执行10次这个轮函数,这个轮函数的前9次执行的操作是一样的,只有第10次有所不同。也就是说,一个明文分组会被加密10轮。AES的核心就是实现一轮中的所有操作。
AES的处理单位是字节,128位的输入明文分组P和输入密钥K都被分成16个字节,分别记为P = P0 P1 … P15 和 K = K0 K1 … K15。如,明文分组为P = abcdefghijklmnop,其中的字符a对应P0,p对应P15。一般地,明文分组用字节为单位的正方形矩阵描述,称为状态矩阵。在算法的每一轮中,状态矩阵的内容不断发生变化,最后的结果作为密文输出。该矩阵中字节的排列顺序为从上到下、从左至右依次排列(a00,a10,a20,a30,a01,a11,a21,a31 …的顺序),如下图所示:
现在假设明文分组P为"abcdefghijklmnop",则对应上面生成的状态矩阵图如下:
类似地,128位密钥也是用字节为单位的矩阵表示,矩阵的每一列被称为1个32位比特字,在矩阵中字是案列排序。通过密钥编排函数该密钥矩阵被扩展成一个44个字组成的序列W[0],W[1], … ,W[43],该序列的前4个元素W[0],W[1],W[2],W[3]是原始密钥,用于加密运算中的初始密钥加;后面40个字分为10组,每组4个字(128比特)分别用于10轮加密运算中的轮密钥加,如下图所示:
上图中,设K = “abcdefghijklmnop”,则K0 = a, K15 = p, W[0] = K0 K1 K2 K3 = “abcd”。3.加密解密的详细结构
Rijndael 的轮函数由 4 个不同的计算部件组成,分别是:
- 字节代换 (ByteSub),非线性层,用一个S盒完成分组的字节到字节的代替。
- 行移位SR(ShiftRow),线性层,一个简单的置换。
- 列混合MC(MixColumn),线性层,利用域GF(28)上的算术特性的一个代替。
- 密钥加ARK(AddRoundKey),线性层,当前分组和扩展密钥的一部分进行按位异或XOR。
AES未使用Feistel结构。AES其前9轮由4个不同的变换组成:字节代替、行移位、列混淆和轮密钥加。最后一轮仅包含三个变换。而在第一轮前面有一个起始的单变换(轮密钥加),可以视为0轮(明文分组P与初始密钥key做异或运算)
AES解密过程仍为10轮,每一轮的操作是加密操作的逆操作。由于AES的4个轮操作都是可逆的,因此,解密操作的一轮就是顺序执行逆行移位、逆字节代换、轮密钥加和逆列混合。同加密操作类似,最后一轮不执行逆列混合,在第1轮解密之前,要执行1次密钥加操作。完整结构如下图:
4.四种轮操作
1.字节代换(SubBytes)
SubBytes()变换是一个基于S盒的非线性置换,它用于将每一个字节通过一个简单的查表操作映射为另一个字节
映射方法:把输入字节的高4位作为S盒的行值,低4位作为列值,然后取出S盒中对应行和列交叉位的元素作为输出;而字节代换逆操作也就是查逆 S 盒来变换。
S盒和逆S盒都是一个16×16个字节的矩阵,包含了8位所能表示的256个数的一个置换和逆置换。
例如,十六进制数{95}对应S盒的9行5列,在S盒中的值为{2A},所以{95}就被代替为{2A}。
逆S盒与其类似,逆推。S盒如下图:
2.行移位操作(线性变换)
行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,4、6、8个字如下图所示:
3.列混合(MixColumn)
列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵,如下图的公式所示:
状态矩阵中的第j列(0 ≤j≤3)的列混合可以表示如下所示:
4.轮密钥加
轮密钥加是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作,如下图所示。其中,密钥Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为32位比特字,包含4个字节;轮密钥加过程可以看成是字逐位异或的结果,也可以看成字节级别或者位级别的操作。也就是说,可以看成S0 S1 S2 S3 组成的32位字与W[4i]的异或运算。
轮密钥由种子密钥通过密钥编排算法得到,轮密钥长度等于分组长度 Nb 。1.密钥编排
密钥编排指从种子密钥得到轮密钥的过程,它由密钥扩展和轮密钥选取两部分组成。
基本原则如下:
1)轮密钥的比特数等于分组长度乘以轮数加1;
例如要将 128 比特的明文经过 10 轮的加密,则总共需要 比特的密钥。
2)种子密钥被扩展成为扩展密钥;
3)轮密钥从扩展密钥中取,其中第1轮密钥取扩展密钥的前 Nb 个字,第 2 轮轮密钥取接下来的 Nb 个字,如此下去。密钥扩展
1)用一个 4 字节字元素的一维数组 W[Nb*(Nr+1)]表示扩展密钥。
2)数组中最开始的 Nk 个字为种子密钥。
3)其它的字由它前面的字经过递归处理后得到。总的来说递归方式如下:
1)如果i不是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁W[i-1]
2)如果i是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁T(W[i-1])其中,T是一个有点复杂的函数。函数T由3部分组成:字循环、字节代换和轮常量异或,这3部分的作用分别如下。
a)字循环:将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]。
b)字节代换:对字循环的结果使用S盒进行字节代换。
c)轮常量异或:将前两步的结果同轮常量Rcon[j]进行异或,其中j表示轮数。
轮常量Rcon[j]是一个字,其值见下表。
5.AES解密
AES的解密算法与加密算法类似(称为逆加密算法),主要区别在于轮密钥要逆序使用,四个基本运算都有对应的逆变换。
AES解密的基本运算中除轮密钥加AddRoundKey不变外(实际上按位异或操作的逆变换是其本身),其余的字节代替SubBytes、行移位ShiftRows、列混淆MixColumns都要进行求逆变换,分别为InvSubBytes、InvShiftRows、InvMixColumns- 逆字节代换
也就是查逆S盒来变换。 - 行移位的逆变换
是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。 - 列混合逆运算
逆向列混合变换可由下图的矩阵乘法定义:
6.AES的python实现
整体代码:
class AesCryption: # 字节替换s盒 s_box = { 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盒 s_I_box = { 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_I_box(self, row): # 逆s盒函数 a = [] for i in range(4): a.append(self.s_I_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_I_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
加密代码:
from AES import AesCryption key = input("key = ") plain = input("plain = ") # cipher = input("cipher = ") aesencrypt = AesCryption(key) print('密钥是:'+key) print('明文是:'+plain) print('密文是:'+aesencrypt.AesEncrypt(plain))
加密实例:
key = 000102030405060708090a0b0c0d0e0f plain = 00112233445566778899aabbccddeeff 密钥是:000102030405060708090a0b0c0d0e0f 明文是:00112233445566778899aabbccddeeff 密文是:69c4e0d86a7b0430d8cdb78070b4c55a Process finished with exit code 0
解密代码:
from AES import AesCryption key = input("key = ") # plain = input("plain = ") cipher = input("cipher = ") aesencrypt = AesCryption(key) print('密钥是:'+key) print('密文是:'+cipher) print('明文是:'+aesencrypt.AesDecrypt(cipher))
解密实例:
key = 000102030405060708090a0b0c0d0e0f cipher = 69c4e0d86a7b0430d8cdb78070b4c55a 密钥是:000102030405060708090a0b0c0d0e0f 密文是:69c4e0d86a7b0430d8cdb78070b4c55a 明文是:00112233445566778899aabbccddeeff Process finished with exit code 0
-
python 实现AES加密算法
2022-03-21 18:10:56从安全性角度推荐CBC加密方法,本文介绍了CBC,ECB两种加密方法的python实现。 CBC 和ECB模式的区别就是: CBC加密需要一个十六位的key(密钥)和一个十六位iv(偏移量) ECB加密不需要iv,只需要key(密钥) 2.模块安装 ...1. AES算法简介
AES算法详解:高级加密标准,它是一种对称加密算法,AES只有一个密钥,这个密钥既用来加密,也用于解密。
AES加密方式有五种:
ECB, CBC, CTR, CFB, OFB
。
从安全性角度推荐CBC加密方法,本文介绍了CBC
,ECB
两种加密方法的python实现。
CBC 和ECB模式的区别就是:- CBC加密需要一个
十六位的key
(密钥)和一个十六位iv
(偏移量) - ECB加密不需要iv,只需要key(密钥)
2.模块安装
在 Windows下使用AES时要安装的是pycryptodome 模块
pip install pycryptodome
在 Linux下使用AES时要安装的是pycrypto模块
pip install pycrypto
3.AES的ECB 模式实现
第一种写法:
import base64 from Crypto.Cipher import AES """ ECB没有偏移量 """ def pad(text): """ #填充函数,使被加密数据的字节码长度是block_size的整数倍 """ count = len(text.encode('utf-8')) add = 16 - (count % 16) entext = text + (chr(add) * add) return entext.encode('utf-8') def add_to_16(text): if len(text.encode('utf-8')) % 16: add = 16 - (len(text.encode('utf-8')) % 16) else: add = 0 text = text + ('\0' * add) return text.encode('utf-8') # 加密函数 def encrypt(text): key = '9999999999999999'.encode('utf-8') text = add_to_16(text) cryptos = AES.new(key=key, mode=AES.MODE_ECB) cipher_text = cryptos.encrypt(text) msg = str(base64.b64encode(cipher_text), encoding="utf8") return msg # 解密后,去掉补足的空格用strip() 去掉 def decrypt(text): key = '9999999999999999'.encode('utf-8') mode = AES.MODE_ECB cryptor = AES.new(key, mode) res = base64.decodebytes(text.encode("utf-8")) plain_text = cryptor.decrypt(res).decode("utf-8").rstrip('\0') return plain_text if __name__ == '__main__': text = 'happy_new_years_2022' res = encrypt(text) # 加密 doc_text = decrypt(res) # 解密 print("加密前数据:", text) print("加密后数据:", res) print("数据解密:", doc_text)
运行结果:
第二种写法:# -*- coding:utf-8 -*- import base64 from Crypto.Cipher import AES class EncryptDate: def __init__(self, key): self.key = key # 初始化密钥 self.length = 16 # 初始化数据块大小 self.aes = AES.new(self.key, AES.MODE_ECB) # 初始化AES,ECB模式的实例 self.unpad = lambda date: date[0:-ord(date[-1])] # 截断函数,去除填充的字符 def pad(self, text): """ #填充函数,使被加密数据的字节码长度是block_size的整数倍 """ count = len(text.encode('utf-8')) add = self.length - (count % self.length) entext = text + (chr(add) * add) return entext def encrypt(self, encrData): # 加密函数 a = self.pad(encrData) res = self.aes.encrypt(a.encode("utf-8")) msg = str(base64.b64encode(res), encoding="utf8") return msg def decrypt(self, decrData): # 解密函数 res = base64.decodebytes(decrData.encode("utf-8")) msg = self.aes.decrypt(res).decode("utf-8") return self.unpad(msg) if __name__ == '__main__': aes_key = "9999999999999999" aes_text = "happy_new_years_2022" eg = EncryptDate(aes_key.encode("utf-8")) encrypt_data = eg.encrypt(aes_text) print("明文数据数据:", eg.decrypt(encrypt_data)) print("加密后数据:", encrypt_data)
3.AES的CBC 模式实现
第一种写法:
import base64 from Crypto.Cipher import AES # 密钥(key), 密斯偏移量(iv) CBC模式加密 def AES_Encrypt(key, data, vi): pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16) data = pad(data) # 字符串补位 cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8')) encryptedbytes = cipher.encrypt(data.encode('utf8')) # 加密后得到的是bytes类型的数据 encodestrs = base64.b64encode(encryptedbytes) # 使用Base64进行编码,返回byte字符串 enctext = encodestrs.decode('utf8') # 对byte字符串按utf-8进行解码 return enctext def AES_Decrypt(key, data, vi): data = data.encode('utf8') res = base64.decodebytes(data) # 将加密数据转换位bytes类型数据 cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8')) text_decrypted = cipher.decrypt(res) unpad = lambda s: s[0:-s[-1]] text_decrypted = unpad(text_decrypted) # 去补位 text_decrypted = text_decrypted.decode('utf8') return text_decrypted if __name__ == '__main__': aes_key = '0CoJUm6Qyw8W8jud' aes_iv = "9999999999999999" data_text = 'dsdadaxdgdfgdfgwer tw4356 45623 462345fas' enctext = AES_Encrypt(aes_key, data_text, aes_iv) text_decrypted = AES_Decrypt(aes_key, enctext, aes_iv) print("原始文本:", data_text) print("AES加密后:", enctext) print("AES解密后:", text_decrypted)
效果如图:
第二种写法:import base64 from Crypto.Cipher import AES class EncryptDate: def __init__(self, key, iv): self.key = key.encode("utf-8") # 初始化密钥 self.iv = iv.encode("utf-8") # 初始化偏移量 self.length = 16 # 初始化数据块大小 self.aes = AES.new(self.key, AES.MODE_CBC, self.iv) # 初始化AES,ECB模式的实例 # 截断函数,去除填充的字符 self.unpad = lambda s: s[0:-s[-1]] def pad(self, text): """ 填充函数,使被加密数据的字节码长度是block_size的整数倍 """ count = len(text.encode('utf-8')) add = self.length - (count % self.length) entext = text + (chr(add) * add) return entext def encrypt(self, encrData): # 加密函数 a = self.pad(encrData) res = self.aes.encrypt(a.encode("utf-8")) msg = str(base64.b64encode(res), encoding="utf8") return msg def decrypt(self, decrData): # 解密函数 res = base64.decodebytes(decrData.encode("utf-8")) msg_text = self.aes.decrypt(res) decrypt_text = self.unpad(msg_text).decode('utf8') return decrypt_text if __name__ == '__main__': aes_key = "0CoJUm6Qyw8W8jud" aes_iv = "9999999999999999" text_data = 'dsdadaxdgdfgdfgwer tw4356 45623 462345fas' encrypt_data = EncryptDate(aes_key, aes_iv).encrypt(text_data) decrypt_data = EncryptDate(aes_key, aes_iv).decrypt(encrypt_data) print("原始数据:", text_data) print("加密后数据:", encrypt_data) print("数据解密:", decrypt_data)
- CBC加密需要一个
-
AES加密算法基于python实现
2021-05-04 20:31:01参考了Python实现AES加密算法(无第三方库)一些基本数据直接复制了过来 加密 一、 基本运算 1. 字节代替subBytes----------用一个S盒完成分组中的按字节的代替 2. 行移位shiftRows-----------一个简单的置换 3. 列...AES加密算法
**最近对这个算法进行了重写,文章地址
- 允许加密任意长度的字符串和文件
- 密钥长度可以是小于16字节的任意字符串
前言:
这篇文章的输入只能是16位16进制表示的字符串。密钥也固定只能是16位的16进制字符串
限制比较多
AES是对称加密算法,本文实现的是128bit密钥的Rijndael算法
采用的语言:python
参考了Python实现AES加密算法(无第三方库)一些基本数据直接复制了过来加密
一、 基本运算
1. 字节代替subBytes----------用一个S盒完成分组中的按字节的代替 2. 行移位shiftRows-----------一个简单的置换 3. 列混淆mixColumns----------一个利用在域GF(2^8)上的算数特性的代替 4. 轮密钥加addRoundKey--------一个利用当前分组和扩展密钥的一部分进行按位异或
二、加密过程
- 128位密钥需要加密10轮 - 在第一轮加密之前之前需要进行一次轮密钥加 - addRoundKey - 前9轮循环执行以下操作: - subBytes - shiftRows - mixColumns - addRoundKey - 最后一轮(即第10轮没有列混淆): - subBytes - shiftRows - addRoundKey
三、基本加密变换
1、1.S盒变换——SubBytes(字节运算) SubBytes()变换是一个基于S盒的非线性置换,它用于将输人或中间态的每一个字节通 过一个简单的查表操作,将其映射为另一个字节。 映射方法是:把输入字节的高4位作为S盒的行值,低4位作为列值,然后取出S盒中对应和列的元素作为输出。 例如:输入为“95”(十六进制表示)的值所对应的S盒的 行值为“9” 列值为“5”, S盒中相应位置的值为“2a”,就说明“95”被映射为“2a”。
S_BOX = [[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76], [0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0], [0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15], [0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75], [0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84], [0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF], [0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8], [0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2], [0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73], [0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB], [0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79], [0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08], [0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A], [0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E], [0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF], [0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]]
subBytes函数代码
def subBytes(self,Matrix,state):#根据传入的Matrix确定实现字节代替(或逆字节代替) #列表推导式 return [Matrix[i][j] for i,j in[(t>>4,t&0xf) for t in state]]
其中Matrix参数是置换需要的S盒,加密的时候传入S_BOX、解密的时候传入I_SOX state为待置换的中间态
2、shiftRows
def shiftRows(self,s): return [s[0],s[1],s[2],s[3], s[5],s[6],s[7],s[4], s[10],s[11],s[8],s[9], s[15],s[12],s[13],s[14]]
- 完成基于行的循环移位操作,输入是一个4x4的矩阵,每一个元素都是一个字节,移位操作为: - 第0行元素位置不变 - 第1行循环左移1个字节——————即5号元素在原来的4号元素的位置上,后面的依次往前移一个下标,而4号元素移到了第1行行尾了,后面以此类推 - 第2行循环左移2个字节 - 第3行循环左移3个字节
三、mixColumns
难点在域GF(2^8)上的乘法def mixColumns(self,matrix,state): ls=[] temp=0x0 for round in range(4): for row in range(4):#矩阵MIX_C的一行乘以state的每一列 for col in range(4): temp^=self.mul_all(matrix[round][col],state[col*4+row]) ls.append(temp) temp=0x0 return ls def mul_all(self,p1,p2):#有限域(G(2^8))上的乘法 result=0x0 pp=p1 temp=0x1 #将p1拆分成符合mul_2函数的参数形式 for i in range(8): if p1==0:#当乘数等于0的时候就跳出循环 break if pp&temp: result^=self.mul_2(temp,p2) temp<<=1 p1>>=1 return result def mul_2(self,p1,p2):#递归处理有限域乘法(处理乘数p1的数据形如:0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80) if p1==1: #p1为乘数,p2为被乘数 return p2 else: return (self.mul_2(p1>>1,(p2<<1&0xff)^(0x1b if p2&0x80 else 0x00)))#result=(p2<<1&0xff)^(0x1b if p2&0x80 else 0x00)中间结果项
后面的直接上代码:
完整代码如下:class AES_128: #列混合矩阵 MIX_C = [[0x2, 0x3, 0x1, 0x1], [0x1, 0x2, 0x3, 0x1], [0x1, 0x1, 0x2, 0x3], [0x3, 0x1, 0x1, 0x2]] I_MIXC = [[0xe, 0xb, 0xd, 0x9], [0x9, 0xe, 0xb, 0xd], [0xd, 0x9, 0xe, 0xb], [0xb, 0xd, 0x9, 0xe]] RCon = [0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000] S_BOX = [[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76], [0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0], [0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15], [0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75], [0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84], [0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF], [0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8], [0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2], [0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73], [0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB], [0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79], [0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08], [0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A], [0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E], [0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF], [0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]] I_SBOX = [[0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB], [0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB], [0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E], [0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25], [0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92], [0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84], [0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06], [0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B], [0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73], [0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E], [0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B], [0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4], [0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F], [0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF], [0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61], [0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D]] def subBytes(self,Matrix,state):#根据传入的Matrix确定实现字节代替(或逆字节代替) return [Matrix[i][j] for i,j in[(t>>4,t&0xf) for t in state]] def mixColumns(self,matrix,state): ls=[] temp=0x0 for round in range(4): for row in range(4):#矩阵MIX_C的一行乘以state的每一列 for col in range(4): temp^=self.mul_all(matrix[round][col],state[col*4+row]) ls.append(temp) temp=0x0 return ls def shiftRows(self,s):#加密时的行移位 return [s[0],s[1],s[2],s[3], s[5],s[6],s[7],s[4], s[10],s[11],s[8],s[9], s[15],s[12],s[13],s[14]] def inShiftRows(self,s):#逆行移位,解密时的行移位 return [s[0],s[1],s[2],s[3], s[7],s[4],s[5],s[6], s[10],s[11],s[8],s[9], s[13],s[14],s[15],s[12]] def addRoundKey(self,state,kw): ls=[0]*16 for row in range(4): for col in range(4): ls[col*4+row]=state[col*4+row]^kw[row*4+col] return ls def mul_2(self,p1,p2):#递归处理有限域乘法(处理乘数p1的数据形如:0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80) if p1==1: #p1为乘数,p2为被乘数 return p2 else: return (self.mul_2(p1>>1,(p2<<1&0xff)^(0x1b if p2&0x80 else 0x00)))#result=(p2<<1&0xff)^(0x1b if p2&0x80 else 0x00)中间结果项 def mul_all(self,p1,p2):#有限域(G(2^8))上的乘法 result=0x0 pp=p1 temp=0x1 for i in range(8): if p1==0:#当乘数等于0的时候就跳出循环 break if pp&temp: result^=self.mul_2(temp,p2) temp<<=1 p1>>=1 return result def keyExpansion(self,key): kw=[key>>96,key>>64&0xffffffff,key>>32&0xffffffff,key&0xffffffff]+[0]*40 for i in range(4,44): temp=kw[i-1] if i%4==0: temp=self.subWord(self.rotWord(temp))^self.RCon[i//4-1] kw[i]=kw[i-4]^temp return [(kw[4*i]>>24,kw[4*i]>>16&0xff,kw[4*i]>>8&0xff,kw[4*i]&0xff, kw[4*i+1]>>24,kw[4*i+1]>>16&0xff,kw[4*i+1]>>8&0xff,kw[4*i+1]&0xff, kw[4*i+2]>>24,kw[4*i+2]>>16&0xff,kw[4*i+2]>>8&0xff,kw[4*i+2]&0xff, kw[4*i+3]>>24,kw[4*i+3]>>16&0xff,kw[4*i+3]>>8&0xff,kw[4*i+3]&0xff)for i in range(11)] def rotWord(self,word): return ((word&0xffffff)<<8) + (word>>24) def subWord(self,word): result=0x0 for i in range(4): temp=word&0xff000000 word<<=8 temp>>=24 result=(result<<8)+self.S_BOX[temp>>4][temp&0xf] return result #加密 def encrypt(self,text,key): kw=self.keyExpansion(key) state=self.slipt(text) state=self.addRoundKey(state,kw[0]) for i in range(1,10): state=self.subBytes(self.S_BOX,state) state=self.shiftRows(state) state=self.mixColumns(self.MIX_C,state) state=self.addRoundKey(state,kw[i]) state=self.subBytes(self.S_BOX,state) state=self.shiftRows(state) state=self.addRoundKey(state,kw[10]) return state def decrypt(self,text,key): kw=self.keyExpansion(key) state=self.slipt(text) state=self.addRoundKey(state,kw[10]) for i in [9,8,7,6,5,4,3,2,1]: state=self.inShiftRows(state) state=self.subBytes(self.I_SBOX,state) state=self.addRoundKey(state,kw[i]) state=self.mixColumns(self.I_MIXC,state) state=self.inShiftRows(state) state=self.subBytes(self.I_SBOX,state) state=self.addRoundKey(state,kw[0]) return state #将输入的16字节进行划分 def slipt(self,text): ls=[0]*16 for i in [3,2,1,0]: for j in [3,2,1,0]: ls[4*j+i]=text&0xff text>>=8 return ls #打印数据 def show(s): for i in range(4): for j in range(4): print(hex(s[4*j+i]),end=' ') print("加密:1 解密: 2 示例:3 退出:0") k=int(input("你要进行的操作:")) my=AES_128() while k!=0: if k==1: text1=int(input("请输入明文:"),16) key1=int(input("请输入密钥:"),16) s=my.encrypt(text1,key1) show(s) elif k==2: ciphertext1=int(input("请输入密文:"),16) key1=int(input("请输入密钥:"),16) s=my.decrypt(ciphertext1,key1) show(s) elif k==3: text=0x3243f6a8885a308d313198a2e0370734 key= 0x2b7e151628aed2a6abf7158809cf4f3c s=my.encrypt(text,key) print("加密后的密文:") show(s) ciphertext=0x3925841d02dc09fbdc118597196a0b32 s=my.decrypt(ciphertext,key) print('解密出的明文:') show(s) print() k=int(input("你要进行的操作:"))
解密:
就是加密的逆变换
-
【图解AES加密算法】AES算法的Python实现 | Rijndael-128 | 对称加密 | 物联网安全
2022-03-24 20:50:45图解AES算法,详细的算法分析,并使用Python进行算法实现 -
AES对称加密算法的Python实现(含基础UI界面)
2022-03-28 16:59:17AES加密算法涉及4种操作,分别是字节替代、行移位、列混淆和轮密钥加,解密算法的每一步分别对应加密算法的逆操作,且所有操作的顺序相反。加解密中每轮的密钥分别由初始密钥经过密钥扩展算法得到。算法中16字节的... -
AES加密算法的详细介绍和python实现
2021-10-16 23:22:01高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。对称加密算法加密和解密用相同的密钥,具体的加密流程如下图: 下面简单介绍下各个部分的作用与意义: 明文P 有意义的字符或比特集,或... -
对称加密之AES算法的python实现
2021-07-18 15:09:52高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图: AES加密方式有五种:ECB... -
Python AES加密模块用法分析
2020-12-15 13:54:35本文实例讲述了Python AES加密模块用法。分享给大家供大家参考,具体如下:AES是新的一种加密模块。在上次介绍过在C语言中如何来OpenSSL中的DES。这次我们来看看Python自带的库如何来使用AES来加解密。其实二者的... -
Python实现aes加密解密多种方法解析
2020-09-16 21:01:31主要介绍了Python实现aes加密解密多种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
Python实现常见的几种加密算法(MD5,SHA-1,HMAC,DES/AES,RSA和ECC)
2020-12-20 08:15:56生活中我们经常会遇到一些加密算法,今天我们就聊聊这些加密算法的Python实现。部分常用的加密方法基本都有对应的Python库,基本不再需要我们用代码实现具体算法。 MD5加密 全称:MD5消息摘要算法(英语:MD5 Message... -
Python3对称加密算法AES、DES3实例详解
2021-01-21 17:25:58本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下: python3.6此库安装方式,需要pip3 install pycryptodome。 如有site-packages中存在crypto、pycrypto,在pip之前,需要pip3 ... -
Python基于pycrypto实现的AES加密和解密算法示例
2020-09-20 15:31:21主要介绍了Python基于pycrypto实现的AES加密和解密算法,结合实例形式分析了Python使用pycrypto模块进行AES加密与解密操作相关实现技巧,需要的朋友可以参考下 -
python系列之:使用AES加密算法实现加密解密工具类
2022-03-18 09:20:58python系列之:使用AES加密算法实现加密解密工具类一、AES加密算法二、补齐密钥长度三、加密代码四、解密代码五、指定密钥种子六、AES加密算法加密解密工具类 一、AES加密算法 高级加密标准(AES)为最常见的对称加密... -
DES 和AES加密算法(python实现)
2021-03-08 22:25:54DES 和AES加密算法(python实现) (1) DES算法 from Crypto.Cipher import DES from binascii import b2a_hex, a2b_hex class MyDESCrypt: def __init__(self, key=''): # 密钥长度必须为64位,也就是8个字节 ... -
python实现aes加密解密
2020-12-15 13:54:43引子:在windows中python3使用 pycryptodemo 模块实现Aes加密解密。Aes加密有多种方式,自己可以上网了解下。 AES是每16位一加密,并且保证key和vi都是16位的。废话不多说直接上代码。import base64from Crypto.... -
密码学 AES算法 Python代码实现
2016-06-06 20:55:53使用Python实现密码学的AES算法 -
使用Python进行AES加密和解密的示例代码
2020-12-25 03:47:02高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael...本科的时候弄过DES加密算法加密计算机文件,而DES加密算法现在基本处于被废弃的状态,所以现在想试试更高级一点的。 DES -
python实现AES加密解密
2020-12-25 21:59:24本文实例为大家分享了python实现AES加密解密的具体代码,供大家参考,具体内容如下 (1)对于AES加密解密相关知识 (2)实现的功能就是输入0-16个字符,然后经过AES的加密解密最后可以得到原先的输入,运行的结果... -
Python实现AES加密(对称加密算法)
2018-11-11 21:20:40from Cryptodome.Cipher import AES from binascii import b2a_hex,a2b_hex from Cryptodome import Random class AesEncryption(object): def __init__(self, key, mode=AES.MODE_CFB): self.... -
Python3和java互通的AES加密算法
2022-01-12 14:06:27参考文章: https://www.cnblogs.com/linuxcat/p/14494630.html ...python环境 python3.7.5 安装包: pip install pycryptodome 很重要 python版本的算法有个问题,就是不能加密中文 代码 from Crypto -
Python实现AES加密,解密的两种方法
2020-12-16 18:46:33# 密钥(key), 密斯偏移量(iv) CBC模式加密 def AES_Encrypt(key, data): vi = '0102030405060708' pad = lambda s: s + (16 - len(s) ) * chr(16 - len(s) ) data = pad(data) # 字符串补位 cipher = AES.... -
Python 的AES加密与解密实现
2020-12-31 09:50:28高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种...AES加密方式有五种:ECB, CBC, CTR, CFB, OFB 1.ECB模式(电子密码本模式:Electroni -
【答辩PPT】AES加密算法实现.ppt
2020-03-02 17:21:18自创性毕业设计论文答辩PPT,有需要参考的朋友拿去 文档记录清晰,格式标准,另外有具体源码,有需要的朋友私信给我索要 -
Python实现AES加密算法(无第三方库)
2019-09-29 17:36:24本文将用Python实现密钥长度为128位的AES算法,若想要详细了解完整的AES算法,请移步官方文档。 首先,我们给出一个AES的总体描述。该算法的执行过程如下: 给定一个明文x和密钥key,将State初始化为x,同时产生11... -
Python 和java 中使用AES加密算法
2020-07-23 17:16:01由于采用微服务架构,各种大大小小的服务少说也有几十个,还一些普通的java项目,python脚本等。将这些所有的项目的数据库密码修改一遍,然后重启,将会是一件工作量巨大工作,经过研究,最终确定的方案时采用统一的... -
AES算法 Python实现
2020-05-13 22:55:56AES加解密算法 Python实现 实现了AES加解密算法。初次尝试,能力有限,代码粗糙,仅供交流学习。五种工作模式也实现了,有需要的可以私聊我。 Talk is cheap. Show me the code. -
Python 实现AES加密、解密
2022-03-30 15:49:48摘要2:python实现AES加密、解密 - 一只小羊 - 博客园 1、pad和unpad分别是填充函数和逆填充函数。因为AES加密对加密文本有长度要求,必须是密钥字节数的倍数。这里的encryptKey在经过base64解码后的长度是16个... -
python 实现aes256加密
2021-01-19 23:24:16基础知识 # 在Linux操作系统下,Python3的默认环境...AES是一种对称加密算法,对称指加密和解密使用同一个密钥; 256指密钥的长度是256bit,即32个英文字符的长度;密钥的长度决定了AES加密的轮数 AES256加密参数 密钥