python如何实现AES/DES加密和解密?


一、引言

  • DES是对称性加密里面常见一种,全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。密钥长度是64位(bit),即8个字节,超过位数密钥被忽略。所谓对称性加密,加密和解密密钥相同。对称性加密一般会按照固定长度(8个字节),把待加密字符串分成块。不足一整块可以使用特殊填充字符。常见的加密解密模式有(ECB,CBC,CTR,OFB,CFB,EAX,OPENPGP)。常见的填充模式有: 'pkcs5','pkcs7','iso10126','ansix923','zero' 类型
  • AES,高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。AES的区块长度固定为128 位,即16个字节,密钥长度则可以是128,192或256位(即16、24和32个字节)。AES分为几种模式,比如ECB,CBC,CFB等等,这些模式除了ECB由于没有使用IV(初始向量)而不太安全,其他模式差别并没有太明显。DES中IV长度固定为8个字节,AES中IV长度固定为16个字节,不同的IV加密后的字符串是不同的,加密和解密需要相同的IV。
  • padding填充:以pkcs7填充为例,如果需要加密的数据的字节码长度不是块大小的整数倍就需要填充。比如数据长度是5个字节,DES就需要填充3个chr(3),即3个‘\x03’,而AES则需要填充13个chr(13)即13个‘\r’。如果数据长度是16个字节,恰好是整数倍,则分别额外填充一个块大小的数据,比如DES则需要填充8个'\x08',而AES则需要填充16个'\x10'

二、安装pycryptodome算法库

pip3 install pycryptodome

三、代码实现

  • DES算法

    # coding:utf-8
    import base64
    from Crypto.Cipher import DES
    
    class DESCrypt:
        def __init__(self,key,mode,iv):
            self.key = key # 密钥
            self.mode = mode # 模式
            self.iv = iv #初始化向量
    
        def encrpyt(self,text):
            '''加密'''
    
            num = DES.block_size - len(text) % DES.block_size #需要填充的字符个数
            text_pad = (text + num*chr(num)).encode('utf-8') #填充后的字节串
            crpytor = DES.new(self.key, self.mode, self.iv)
            encrypt_data = crpytor.encrypt(text_pad) #对数据进行加密
            return base64.b64encode(encrypt_data).decode()
    
        def decrypt(self,text):
            '''解密'''
    
            data = base64.b64decode(text.encode())
            crpytor = DES.new(self.key, self.mode, self.iv)
            decrypt_data = crpytor.decrypt(data) #对数据进行解密
            res = decrypt_data[:-decrypt_data[-1]].decode()#去除多余字符
            return res
    
    
    if __name__ == '__main__':
        #key = random._urandom(8) 可以利用random模块随机生成
        key = b'C\xc5\xa0\x04!\xe3\xd59' #密钥,固定8个字节长度
        mode = DES.MODE_CBC
        iv = b'\x9a\xf8\xad\xeb.\xb7B\xe1' #初始化向量,固定8个字节长度
        des = DESCrypt(key,mode,iv)
        text = input('请输入需要DES加密的数据:')
        en_data = des.encrpyt(text)
        print('%s 经过加密得到:%s'%(text,en_data))
        de_data = des.decrypt(en_data)
        print('%s 经过解密得到:%s'%(en_data,de_data))
  • AES算法

    # coding:utf-8
    import base64
    from Crypto.Cipher import AES
    
    class AESCrypt:
        def __init__(self,key,mode,iv):
            self.key = key # 密钥
            self.mode = mode # 模式
            self.iv = iv #初始化向量
    
        def encrpyt(self,text):
            '''加密'''
    
            num = AES.block_size - len(text) % AES.block_size #需要填充的字符个数
            text_pad = (text + num*chr(num)).encode('utf-8') #填充后的字节串
            crpytor = AES.new(self.key, self.mode, self.iv)
            encrypt_data = crpytor.encrypt(text_pad) #对数据进行加密
            return base64.b64encode(encrypt_data).decode()
    
        def decrypt(self,text):
            '''解密'''
    
            data = base64.b64decode(text.encode())
            crpytor = AES.new(self.key, self.mode, self.iv)
            decrypt_data = crpytor.decrypt(data) #对数据进行解密
            res = decrypt_data[:-decrypt_data[-1]].decode()#去除多余字符
            return res
    
    
    if __name__ == '__main__':
        #key = random._urandom(16) 可以利用random模块随机生成
        key = b'\xc7(\xa4rq{\x89r\xd05kH\xbf^\x8a\x16' #密钥,长度可以是16,24或32个字节
        mode = AES.MODE_CBC
        iv = b'-\x95)\x82\x1a\x00\xde/^:\xd3\xbeXK9\xd2' #初始化向量,固定16个字节长度
        aes = AESCrypt(key,mode,iv)
        text = input('请输入需要AES加密的数据:')
        en_data = aes.encrpyt(text)
        print('%s 经过加密得到:%s'%(text,en_data))
        de_data = aes.decrypt(en_data)
        print('%s 经过解密得到:%s'%(en_data,de_data))