实例详解AES算法

AES算法流程

  稍微百度下就可知道,AES算法分为四个步骤:轮密钥加,字节代替,行移位和列混淆,本文以一个实例来讲解AES算法中的每一个步骤干了什么,精确到每个数字的变换。

写在前面

  AES算法其实有很多种,根据秘钥长度的不同分为AES-128,AES-192,AES-256,本文以AES-128为例。
  至于AES的加密模式,ECB,CBC等,其实和AES加密流程没有关系,不同的模式只是对输入的数据做处理(异或等),加密过程没有丝毫差别。
  最后的实现采用python完成,无第三方模块。

密钥扩展

  在开始加密之前,至少需要一个密钥,AES-128代表密钥长度为128位,也就是16字节。而加密流程一共要循环10轮,每一轮都需要不同的密钥,我们自然不可能设置长度为1280位的密钥,所以需要密钥扩展这个步骤,这个流程将产生10组长度均为128位的密钥。
假设现在有个密钥为’2b7e151628aed2a6abf7158809cf4f3c’,那么扩展秘钥是多少?
  很明显,这个密钥长度是16字节(128位),每两位十六进制的数代表1字节。那么可以将这个密钥化为矩阵的形式:
  在这里插入图片描述
  下一步,官方说法是将初始密钥转为4个32位的字,其实就是将这个密钥分成四组,每一列就是一组,这样就有了四个变量:W0=2B7E1516,W1=28AED2A6,W2=ABF71588,W3=09CF4F3C。
  现在,就要求扩展秘钥了,其实就是求W4,W5,W6…W43,而且很明显,每四个W组成完整的一组密钥。
  怎么求呢?现在先交个底,求每组密钥的第一个分组(W4,W8,W12…)比其他的分组要复杂得多。
  先把公式给出来,看不懂也没关系,有个印象就好:
  在这里插入图片描述
  可以看到,在求W4,W8…时走的是另一条路,重点在于函数g干了什么,我也不想直接甩概念性的东西出来,那个没有意义,还是看实例来的清楚。
  现在是正式的过程,W4很明显是W0与g(W3)的进行异或得结果,那么函数g对W3干了什么?下面就是。
  先将W3左移一个字节,得到W3’=CF4F3C09,然后将这个值进行S盒映射,这个S盒呢,是个固定的东西,可以理解为一个一对一的字典,它的样子如下:
在这里插入图片描述
  查字典的方法不用我多说,将W3’进行S盒映射后,得到W3"=8A84EB01。
  有些烧脑了,现在呢要将W3"与一个叫做Rcon的向量异或,这个向量长这样:
  Rcon=[0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36]
  其实Rcon就是一个长度为10的数组,里面的每个数字都是十六进制形式,计算的密钥分组是属于哪个密钥的,就与Rcon中对应序号的值做异或,比如现在所求得W4属于第一组密钥,那么W3"就要与RCon[0]做异或,以此类推,求第十组密钥W40时需要W39"与Rcon[9]做异或。
  现在好像有问题了,这两个值位数不一样怎么异或?其实很简单,就像下面这样:
  在这里插入图片描述
  不足的位数在后面补0就行了,实质上所有Rcon中的值都只影响W3"的第一个字节(前8位),通过异或,就得到了W3"’,写成十六进制形式是W3"’=8B84EB01。
  上述呢,其实就是函数g干的事,下面就可以得出结果了。
  最后,将W3"'与W0进行异或,就得到了W4,也就是第一组扩展密钥的第一组。
  在这里插入图片描述
  将W4写成十六进制形式W4=A0FAFE17。
  然后,就是把第一组扩展密钥的其他分组(W5,W6,W7)求出来,这三组就简单得多,根据公式,W5是W1与W4异或得到,W6是W2与W5异或得到,W7是W3与W5异或得到,过程如下:
  在这里插入图片描述
  将W5写成十六进制形式就是W5=88542CB1,以此类推,W6=23A33939,W7=2A6C7605。
  现在,就完整求出了第一组扩展密钥,同样写成矩阵形式:
  在这里插入图片描述
下一步,就是求扩展密钥的第二组(W8,W9,W10,W11),过程和上面几乎一样,W8需要W4与g(W7)异或得到,其余的就是直接异或。直至求出第十组扩展密钥。

加密过程

  密钥有了,现在来完整梳理一下加密的流程,其实百度就一大堆,这里简单说一下,加密过程就是:先进行一次轮密钥加(使用初始秘钥),然后循环9次字节代替,行移位,列混淆,轮密钥加(使用9组扩展秘钥),最后再进行一次字节代替,行移位,轮密钥加(使用最后一组扩展秘钥)。

轮密钥加

  初始时刻,需要对明文进行处理,使其长度变为和密钥一样的128位,这里先不讨论,因为这不是加密的过程,后面我会放上详细的明文初始化过程。
  现在,我们已经有了经过处理的明文’3243f6a8885a308d313198a2e0370734’,同样写成4×4的矩阵形式:
  在这里插入图片描述
  那么轮密钥加之后的结果是多少?假设密钥如下:
  在这里插入图片描述
  轮密钥加其实很简单,其实就是明文与密文的异或运算而已,只是计算过程繁杂。
  相同位置的明文和密文都化为二进制形式,进行异或运算,以第一个字节为例:
  在这里插入图片描述
  其他结果依次类推,异或后的矩阵为:
  在这里插入图片描述

字节代替

  这个比较简单,字节代替是通过S盒映射完成的,和密钥扩展的S盒一样,可以直接查S盒。跟查字典一样,和前面密钥扩展的步骤一模一样。上面经过轮密钥加的矩阵再经过字节代替的结果如下:
  在这里插入图片描述

行移位

这个也比较简单,就是矩阵的第一行不变,第二行循环左移一位,第三行循环左移两位,第四行循环左移三位,如下:
  在这里插入图片描述

列混淆

  我认为列混淆是AES加密中最复杂的了,但过程却是一句话就可以概括:左乘一个固定的矩阵。
  固定矩阵如下:
  在这里插入图片描述
  过程图解如下:
  在这里插入图片描述

  在这里插入图片描述
  “⊕”是异或,但那个“×”号不是简单的乘法,规则如下:

  1. 满足乘法分配律,即03×S=01×S⊕02×S。
  2. ×01和普通乘法×1一样,是其本身。
  3. ×02表示左移一位,最右边补0,若原始的数值最高位为1,需要将移位后的结果与1B(00011011)进行异或,如果不是则不用异或。
      假设原始矩阵为在这里插入图片描述求经过列混淆的矩阵。
      同样以第一个字节为例,左乘是行×列,即固定矩阵的一行与原始矩阵的一列相乘。
    在这里插入图片描述
      其他元素是同样的方法,最终得到的结果矩阵如下:
      在这里插入图片描述
    至此,AES加密算法的所有步骤都已经介绍完毕,剩下的就是上述步骤的不断重复。

明文初始化

  关于明文的初始化,就是将明文化为128位(16字节)的过程,转化过程其实很简单,就是将数据(可识别的文字,如hello word)转为字节流,然后再将字节流转为十六进制字符串就OK,转换的方法百度一大堆。
  稍微有点儿问题的就是假设转换的字符串的位数不够128位怎么办?其实这个就是AES加密中的字符填充问题,将原本不足128位的字符填充至128位。至于超过128位的,分组就可以了,一组128位,最后一组同样需要字符填充,然后将每组数据加密后得到的密文连接起来就是完整密文。
  字符填充的办法,其实也是百度一大堆的,这里简单说两种:

  1. PKCS7Padding:差几个字节就填充几,假设明文有10个字节,距离16字节差6字节,就在十六进制字符串后添加6个06,如果刚好16字节,就要在后面添加16个16。
  2. ZerosPadding:缺多少补多少个0,差6个字节就在后面补6个00。

关于解密

  解密其实就是加密的逆推,第一步同样是轮密钥加,而后进入循环解密阶段,一共10轮,按顺序分别执行逆行移位,逆字节代替,轮密钥加,逆向列混淆,同样第10轮去掉逆向列混淆输出明文,但此时扩展秘钥的顺序要反过来。
  逆行移位:第一行不变,第二行循环右移一位,第三行循环右移两位,第四行循环右移三位。
  逆字节代替:操作步骤和字节代替一样,只不过需要映射的S盒变成了逆S盒,其实就是S盒反过来,键值互换,这点用python做非常方便。
  逆列混淆:步骤和列混淆一样,仅仅是固定矩阵不同。
  在这里插入图片描述
  这里的乘法也是和列混淆中的乘法一样,所有的9,B,D,E其实都是通过分解为1或者2进行计算的。
  逆列混淆矩阵和列混淆矩阵的乘积刚好是单位矩阵。

实现(python)

  python解释器是python3.6

# -*- coding: utf-8 -*-

import re
import binascii

class Aes:
    s_box = {  # 字节替换s盒
        '0x00': '0x63', '0x01': '0x7c', '0x02': '0x77', '0x03': '0x7b', '0x04': '0xf2', '0x05': '0x6b', '0x06': '0x6f', '0x07': '0xc5', '0x08': '0x30', '0x09': '0x01', '0x0a': '0x67', '0x0b': '0x2b', '0x0c': '0xfe', '0x0d': '0xd7', '0x0e': '0xab', '0x0f': '0x76',
        '0x10': '0xca', '0x11': '0x82', '0x12': '0xc9', '0x13': '0x7d', '0x14': '0xfa', '0x15': '0x59', '0x16': '0x47', '0x17': '0xf0', '0x18': '0xad', '0x19': '0xd4', '0x1a': '0xa2', '0x1b': '0xaf', '0x1c': '0x9c', '0x1d': '0xa4', '0x1e': '0x72', '0x1f': '0xc0',
        '0x20': '0xb7', '0x21': '0xfd', '0x22': '0x93', '0x23': '0x26', '0x24': '0x36', '0x25': '0x3f', '0x26': '0xf7', '0x27': '0xcc', '0x28': '0x34', '0x29': '0xa5', '0x2a': '0xe5', '0x2b': '0xf1', '0x2c': '0x71', '0x2d': '0xd8', '0x2e': '0x31', '0x2f': '0x15',
        '0x30': '0x04', '0x31': '0xc7', '0x32': '0x23', '0x33': '0xc3', '0x34': '0x18', '0x35': '0x96', '0x36': '0x05', '0x37': '0x9a', '0x38': '0x07', '0x39': '0x12', '0x3a': '0x80', '0x3b': '0xe2', '0x3c': '0xeb', '0x3d': '0x27', '0x3e': '0xb2', '0x3f': '0x75',
        '0x40': '0x09', '0x41': '0x83', '0x42': '0x2c', '0x43': '0x1a', '0x44': '0x1b', '0x45': '0x6e', '0x46': '0x5a', '0x47': '0xa0', '0x48': '0x52', '0x49': '0x3b', '0x4a': '0xd6', '0x4b': '0xb3', '0x4c': '0x29', '0x4d': '0xe3', '0x4e': '0x2f', '0x4f': '0x84',
        '0x50': '0x53', '0x51': '0xd1', '0x52': '0x00', '0x53': '0xed', '0x54': '0x20', '0x55': '0xfc', '0x56': '0xb1', '0x57': '0x5b', '0x58': '0x6a', '0x59': '0xcb', '0x5a': '0xbe', '0x5b': '0x39', '0x5c': '0x4a', '0x5d': '0x4c', '0x5e': '0x58', '0x5f': '0xcf',
        '0x60': '0xd0', '0x61': '0xef', '0x62': '0xaa', '0x63': '0xfb', '0x64': '0x43', '0x65': '0x4d', '0x66': '0x33', '0x67': '0x85', '0x68': '0x45', '0x69': '0xf9', '0x6a': '0x02', '0x6b': '0x7f', '0x6c': '0x50', '0x6d': '0x3c', '0x6e': '0x9f', '0x6f': '0xa8',
        '0x70': '0x51', '0x71': '0xa3', '0x72': '0x40', '0x73': '0x8f', '0x74': '0x92', '0x75': '0x9d', '0x76': '0x38', '0x77': '0xf5', '0x78': '0xbc', '0x79': '0xb6', '0x7a': '0xda', '0x7b': '0x21', '0x7c': '0x10', '0x7d': '0xff', '0x7e': '0xf3', '0x7f': '0xd2',
        '0x80': '0xcd', '0x81': '0x0c', '0x82': '0x13', '0x83': '0xec', '0x84': '0x5f', '0x85': '0x97', '0x86': '0x44', '0x87': '0x17', '0x88': '0xc4', '0x89': '0xa7', '0x8a': '0x7e', '0x8b': '0x3d', '0x8c': '0x64', '0x8d': '0x5d', '0x8e': '0x19', '0x8f': '0x73',
        '0x90': '0x60', '0x91': '0x81', '0x92': '0x4f', '0x93': '0xdc', '0x94': '0x22', '0x95': '0x2a', '0x96': '0x90', '0x97': '0x88', '0x98': '0x46', '0x99': '0xee', '0x9a': '0xb8', '0x9b': '0x14', '0x9c': '0xde', '0x9d': '0x5e', '0x9e': '0x0b', '0x9f': '0xdb',
        '0xa0': '0xe0', '0xa1': '0x32', '0xa2': '0x3a', '0xa3': '0x0a', '0xa4': '0x49', '0xa5': '0x06', '0xa6': '0x24', '0xa7': '0x5c', '0xa8': '0xc2', '0xa9': '0xd3', '0xaa': '0xac', '0xab': '0x62', '0xac': '0x91', '0xad': '0x95', '0xae': '0xe4', '0xaf': '0x79',
        '0xb0': '0xe7', '0xb1': '0xc8', '0xb2': '0x37', '0xb3': '0x6d', '0xb4': '0x8d', '0xb5': '0xd5', '0xb6': '0x4e', '0xb7': '0xa9', '0xb8': '0x6c', '0xb9': '0x56', '0xba': '0xf4', '0xbb': '0xea', '0xbc': '0x65', '0xbd': '0x7a', '0xbe': '0xae', '0xbf': '0x08',
        '0xc0': '0xba', '0xc1': '0x78', '0xc2': '0x25', '0xc3': '0x2e', '0xc4': '0x1c', '0xc5': '0xa6', '0xc6': '0xb4', '0xc7': '0xc6', '0xc8': '0xe8', '0xc9': '0xdd', '0xca': '0x74', '0xcb': '0x1f', '0xcc': '0x4b', '0xcd': '0xbd', '0xce': '0x8b', '0xcf': '0x8a',
        '0xd0': '0x70', '0xd1': '0x3e', '0xd2': '0xb5', '0xd3': '0x66', '0xd4': '0x48', '0xd5': '0x03', '0xd6': '0xf6', '0xd7': '0x0e', '0xd8': '0x61', '0xd9': '0x35', '0xda': '0x57', '0xdb': '0xb9', '0xdc': '0x86', '0xdd': '0xc1', '0xde': '0x1d', '0xdf': '0x9e',
        '0xe0': '0xe1', '0xe1': '0xf8', '0xe2': '0x98', '0xe3': '0x11', '0xe4': '0x69', '0xe5': '0xd9', '0xe6': '0x8e', '0xe7': '0x94', '0xe8': '0x9b', '0xe9': '0x1e', '0xea': '0x87', '0xeb': '0xe9', '0xec': '0xce', '0xed': '0x55', '0xee': '0x28', '0xef': '0xdf',
        '0xf0': '0x8c', '0xf1': '0xa1', '0xf2': '0x89', '0xf3': '0x0d', '0xf4': '0xbf', '0xf5': '0xe6', '0xf6': '0x42', '0xf7': '0x68', '0xf8': '0x41', '0xf9': '0x99', '0xfa': '0x2d', '0xfb': '0x0f', '0xfc': '0xb0', '0xfd': '0x54', '0xfe': '0xbb', '0xff': '0x16'
    }
    ns_box = {  # 逆字节替换s盒
    }

    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']
    ]
    ReMatrix = [  # 逆列混淆
        ['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):
            for j in range(0, 8, 2):
                self.subkey[i].append("0x" + key[i * 8 + j:i * 8 + j + 2])  # 将密钥变成二维矩阵
        # print(self.subkey)
        for i in range(4, 44):  # 生成密钥
            if i % 4 != 0:  # 如果不是4的倍数,那么直接异或
                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])
                # print(tmp1)
                for m in range(4):
                    tmp1[m] = self.s_box[tmp1[m]]
                # tmp1 = self.s_box['cf']  # 字节代替
                tmp1 = xor_32(tmp1, self.Rcon[i / 4])  # 和Rcon异或
                self.subkey.append(xor_32(tmp1, self.subkey[i - 4]))
        # print(self.subkey)

    def AddRoundKey(self, round):  # 轮密钥加
        for i in range(4):
            self.plaintext[i] = xor_32(self.plaintext[i], self.subkey[round * 4 + i])
        # print(self.plaintext)

    def PlainSubBytes(self):  # 字节代替
        for i in range(4):
            for j in range(4):
                self.plaintext[i][j] = self.s_box[self.plaintext[i][j]]
        # print(self.plaintext)

    def RePlainSubBytes(self):  # 逆字节代替
        for i in range(4):
            for j in range(4):
                self.plaintext[i][j] = self.ns_box[self.plaintext[i][j]]

    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
        # print(self.plaintext)

    def ReShiftRows(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 MixColumns(self):  # 列混淆
        for i in range(4):
            for j in range(4):
                self.plaintext1[i].append(MatrixMulti(self.Matrix[j], self.plaintext[i]))
        # print(self.plaintext1)

    def ReMixColumns(self):  # 逆列混淆
        for i in range(4):
            for j in range(4):
                self.plaintext1[i].append(MatrixMulti(self.ReMatrix[j], self.plaintext[i]))

    def AESEncryption(self, plaintext):  # AES单组加密函数
        self.plaintext = [[], [], [], []]
        for i in range(4):
            for j in range(0, 8, 2):
                self.plaintext[i].append("0x" + plaintext[i * 8 + j:i * 8 + j + 2])
        self.AddRoundKey(0)
        for i in range(9):
            self.PlainSubBytes()
            self.ShiftRows()
            self.MixColumns()
            self.plaintext = self.plaintext1
            self.plaintext1 = [[], [], [], []]  # 重置
            self.AddRoundKey(i + 1)

        self.PlainSubBytes()  # 最后一轮字节代替
        self.ShiftRows()  # 最后一轮行移位
        self.AddRoundKey(10)  # 最后一轮轮密钥加
        return Matrixtostr(self.plaintext)

    def AESDecryption(self, cipher):  # AES单组解密函数
        self.plaintext = [[], [], [], []]
        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.ns_box = dict(zip(self.s_box.values(), self.s_box.keys()))  # s盒键值互换,变为逆S盒
        # print(self.ns_box)
        self.AddRoundKey(10)
        for i in range(9):
            self.ReShiftRows()
            self.RePlainSubBytes()
            self.AddRoundKey(9-i)
            self.ReMixColumns()
            self.plaintext = self.plaintext1
            self.plaintext1 = [[], [], [], []]
        self.ReShiftRows()
        self.RePlainSubBytes()
        self.AddRoundKey(0)
        return Matrixtostr(self.plaintext)

    def Encryption(self, text):  # 加密函数
        group = PlaintextGroup(TextToByte(text), 32, 1)
        # print(group)
        cipher = ""
        for i in range(len(group)):
            cipher = cipher + self.AESEncryption(group[i])
        return cipher

    def Decryption(self, cipher):  # 解密函数
        group = PlaintextGroup(cipher, 32, 0)
        # print(group)
        text = ''
        for i in range(len(group)):
            text = text + self.AESDecryption(group[i])
        text = ByteToText(text)
        return text


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 hextobin(word):  # 把十六进制转换成二进制
    word = bin(int(word, 16))[2:]  # 去除掉最前面的0b
    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')


def MatrixMulti(s1, s2):  # 列混淆中的矩阵乘法
    result = []
    s3 = []
    for i in range(4):
        s3.append(hextobin(s2[i]))  # s3保存原始矩阵一行的四个二进制值
    for i in range(4):
        result.append(MultiProcess(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 MultiProcess(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, MultiProcess(2, MultiProcess(2, MultiProcess(2, b))))
    elif a == 11:
        tmp_b = b
        return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, b)))
    elif a == 13:
        tmp_b = b
        return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
    elif a == 14:
        return xor_8(MultiProcess(2, b), xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))


def Matrixtostr(matrix):  # 矩阵转成字符串
    result = ""
    for i in range(4):
        for j in range(4):
            result += matrix[i][j][2:]
    return result


def PlaintextGroup(plaintext, length, flag):  # 明文分组和填充
    group = re.findall('.{'+str(length)+'}', plaintext)
    group.append(plaintext[len(group)*length:])
    if group[-1] == '' and flag:
        group[-1] = '16161616161616161616161616161616'
    elif len(group[-1]) < length and flag:
        tmp = int((length-len(group[-1])) / 2)
        if tmp < 10:
            for i in range(tmp):
                group[-1] = group[-1] + '0'+str(tmp)
        else:
            for i in range(tmp):
                group[-1] = group[-1] + str(tmp)
    elif not flag:
        del group[-1]
    return group


def TextToByte(words):  # 明文转成十六进制字节流
    text = words.encode('utf-8').hex()
    return text


def ByteToText(encode):  # 十六进制字节流转成明文
    tmp = int(encode[-2:])
    word = ''
    for i in range(len(encode)-tmp*2):
        word = word + encode[i]
    # print(word)
    word = bytes.decode(binascii.a2b_hex(word))
    return word


key = '2b7e151628aed2a6abf7158809cf4f3c'
# plaintext = '68656c6c6f20776f726c640505050505'
# A1 = Aes(key)
# abc = A1.AESEncryption(plaintext)
# print(abc)
# print(A1.AESDecryption(abc))
AESDemo = Aes(key)
plaintext = input("请输入要加密的文字:\n")
a = AESDemo.Encryption(plaintext)
print("密文为:" + a)
print("明文为:" + AESDemo.Decryption(a))

测试

在这里插入图片描述
  其实这个程序有个小小的bug,后面再想想能不能消除吧,就这样了。

  • 22
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值