精华内容
下载资源
问答
  • 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的异常。

    更多相关内容
  • 它是一种对称加密算法,与上一篇博文提到过的RSA非对称算法不同,AES只有一个密钥,这个密钥既用来加密,也用于解密。 AES只是个基本算法,实现AES有几种模式,主要有ECB、CBC、CFB和OFB这几种(其实还有个CTR): 1...
  • AES加密算法原理及python实现AES对称加密算法1.Rijndael的设计思想2.AES的基本结构3.加密解密的详细结构4.四种轮操作1.字节代换(SubBytes)2.行移位操作(线性变换)3.列混合(MixColumn)4.轮密钥加1.密钥编排5.AES...

    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)
    
    展开全文
  • 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算法,详细的算法分析,并使用Python进行算法实现
  • AES加密算法涉及4种操作,分别是字节替代、行移位、列混淆和轮密钥加,解密算法的每一步分别对应加密算法的逆操作,且所有操作的顺序相反。加解密中每轮的密钥分别由初始密钥经过密钥扩展算法得到。算法中16字节的...
  • AES加密算法的详细介绍和python实现

    千次阅读 2021-10-16 23:22:01
    高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。对称加密算法加密和解密用相同的密钥,具体的加密流程如下图: 下面简单介绍下各个部分的作用与意义: 明文P 有意义的字符或比特集,或...
  • 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图: AES加密方式有五种:ECB...
  • 本文实例讲述了Python AES加密模块用法。分享给大家供大家参考,具体如下:AES是新的一种加密模块。在上次介绍过在C语言中如何来OpenSSL中的DES。这次我们来看看Python自带的库如何来使用AES来加解密。其实二者的...
  • 主要介绍了Python实现aes加密解密多种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 生活中我们经常会遇到一些加密算法,今天我们就聊聊这些加密算法Python实现。部分常用的加密方法基本都有对应的Python库,基本不再需要我们用代码实现具体算法。 MD5加密 全称:MD5消息摘要算法(英语:MD5 Message...
  • 本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下: python3.6此库安装方式,需要pip3 install pycryptodome。 如有site-packages中存在crypto、pycrypto,在pip之前,需要pip3 ...
  • 主要介绍了Python基于pycrypto实现AES加密和解密算法,结合实例形式分析了Python使用pycrypto模块进行AES加密与解密操作相关实现技巧,需要的朋友可以参考下
  • python系列之:使用AES加密算法实现加密解密工具类一、AES加密算法二、补齐密钥长度三、加密代码四、解密代码五、指定密钥种子六、AES加密算法加密解密工具类 一、AES加密算法 高级加密标准(AES)为最常见的对称加密...
  • DES 和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....
  • 使用Python实现密码学的AES算法
  • 高级加密标准(英语: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:40
    from 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....
  • 参考文章: https://www.cnblogs.com/linuxcat/p/14494630.html ...python环境 python3.7.5 安装包: pip install pycryptodome 很重要 python版本的算法有个问题,就是不能加密中文 代码 from Crypto
  • # 密钥(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....
  • 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种...AES加密方式有五种:ECB, CBC, CTR, CFB, OFB  1.ECB模式(电子密码本模式:Electroni
  • 自创性毕业设计论文答辩PPT,有需要参考的朋友拿去 文档记录清晰,格式标准,另外有具体源码,有需要的朋友私信给我索要
  • Python实现AES加密算法(无第三方库)

    千次阅读 多人点赞 2019-09-29 17:36:24
    本文将用Python实现密钥长度为128位的AES算法,若想要详细了解完整的AES算法,请移步官方文档。 首先,我们给出一个AES的总体描述。该算法的执行过程如下: 给定一个明文x和密钥key,将State初始化为x,同时产生11...
  • 由于采用微服务架构,各种大大小小的服务少说也有几十个,还一些普通的java项目,python脚本等。将这些所有的项目的数据库密码修改一遍,然后重启,将会是一件工作量巨大工作,经过研究,最终确定的方案时采用统一的...
  • AES算法 Python实现

    千次阅读 2020-05-13 22:55:56
    AES加解密算法 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加密参数 密钥

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,915
精华内容 2,766
关键字:

aes加密算法python实现