AES加密算法原理及python实现

AES加密算法原理及python实现

  • AES对称加密算法
    • 1.Rijndael的设计思想
    • 2.AES的基本结构
    • 3.加密解密的详细结构
    • 4.四种轮操作
      • 1.字节代换(SubBytes)
      • 2.行移位操作(线性变换)
      • 3.列混合(MixColumn)
      • 4.轮密钥加
        • 1.密钥编排
    • 5.AES解密
    • 6.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加密算法原理及python实现_第1张图片
  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 …的顺序),如下图所示:
AES加密算法原理及python实现_第2张图片
  现在假设明文分组P为"abcdefghijklmnop",则对应上面生成的状态矩阵图如下:
AES加密算法原理及python实现_第3张图片
  类似地,128位密钥也是用字节为单位的矩阵表示,矩阵的每一列被称为1个32位比特字,在矩阵中字是案列排序。通过密钥编排函数该密钥矩阵被扩展成一个44个字组成的序列W[0],W[1], … ,W[43],该序列的前4个元素W[0],W[1],W[2],W[3]是原始密钥,用于加密运算中的初始密钥加;后面40个字分为10组,每组4个字(128比特)分别用于10轮加密运算中的轮密钥加,如下图所示:
AES加密算法原理及python实现_第4张图片
  上图中,设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次密钥加操作。完整结构如下图:
AES加密算法原理及python实现_第5张图片

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盒如下图:
AES加密算法原理及python实现_第6张图片

2.行移位操作(线性变换)

  行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,4、6、8个字如下图所示:
AES加密算法原理及python实现_第7张图片
AES加密算法原理及python实现_第8张图片

3.列混合(MixColumn)

  列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵,如下图的公式所示:
AES加密算法原理及python实现_第9张图片
  状态矩阵中的第j列(0 ≤j≤3)的列混合可以表示如下所示:
AES加密算法原理及python实现_第10张图片

4.轮密钥加

  轮密钥加是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作,如下图所示。其中,密钥Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为32位比特字,包含4个字节;轮密钥加过程可以看成是字逐位异或的结果,也可以看成字节级别或者位级别的操作。也就是说,可以看成S0 S1 S2 S3 组成的32位字与W[4i]的异或运算。
AES加密算法原理及python实现_第11张图片
AES加密算法原理及python实现_第12张图片
  轮密钥由种子密钥通过密钥编排算法得到,轮密钥长度等于分组长度 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]是一个字,其值见下表。
AES加密算法原理及python实现_第13张图片

5.AES解密

  AES的解密算法与加密算法类似(称为逆加密算法),主要区别在于轮密钥要逆序使用,四个基本运算都有对应的逆变换。
  AES解密的基本运算中除轮密钥加AddRoundKey不变外(实际上按位异或操作的逆变换是其本身),其余的字节代替SubBytes、行移位ShiftRows、列混淆MixColumns都要进行求逆变换,分别为InvSubBytes、InvShiftRows、InvMixColumns

  • 逆字节代换
    也就是查逆S盒来变换。
  • 行移位的逆变换
    是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。
  • 列混合逆运算
    逆向列混合变换可由下图的矩阵乘法定义:
    AES加密算法原理及python实现_第14张图片

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

你可能感兴趣的:(AES对称加密算法,算法,python)