python AES加密解密,key的长度不受限制

来源:python AES加密解密,key的长度不受限制 from CDSN by 雨丶花丶石

最近用pypisder爬虫,发现其json是一坨乱码,后来查了查是用了AES加密,但找了网上N多教程都是基于key长度受限于16,24,32位。 但我需要的是不限长度的key。最终找到了下面转载的教程。

说明:

1、下面列举了2种加密解密的方法,一个是key的长度不收限制,必须为16,24,32位,另外一种就是key的长度不受限制

2、这里同样使用了PKCS5Padding做填充

3、之前说了,想实现python 加密解密,与go互通,也就是python 加密go解密,或者go加密,python解密,这2种情形的话,这里一定要选择下面的第一种方式,也就是key的值是受限制的,至于key不受限制,如何互通,这里先不介绍,后面在说明

直接上代码:

方式一、key 值受限制

from Crypto import Random
from Crypto.Cipher import AES
import base64
from hashlib import md5
from binascii import b2a_hex, a2b_hex
BLOCK_SIZE = AES.block_size

def pad(data):
    length = BLOCK_SIZE - (len(data) % BLOCK_SIZE)
    #return data + (chr(length) * length).encode()
    return data.encode(encoding='utf-8') + (chr(length)*length).encode(encoding='utf-8')


def unpad(data):
    return data[:-(data[-1] if type(data[-1]) == int else ord(data[-1]))]

def encrypt(message, key):
    salt = Random.new().read(BLOCK_SIZE+len(pad(message)))
    iv = salt[:BLOCK_SIZE]
    key = key.encode('utf-8')
    aes = AES.new(key, AES.MODE_CBC, iv)
    return base64.b64encode(iv+aes.encrypt(pad(message)))

def decrypt(encrypted, key):
    encrypted = base64.b64decode(encrypted)
    iv = encrypted[0:16]
    key =  key.encode('utf-8')
    aes = AES.new(key, AES.MODE_CBC, iv)
    return unpad(aes.decrypt(encrypted[BLOCK_SIZE:]))
if __name__ == '__main__':

    key = 'ABCDEFGHIJKLMNOp'
    data = 'oracless'
    encrypt_data = encrypt(data, key)
    print(encrypt_data)

    decrypt_data = decrypt(encrypt_data, key)
    print(decrypt_data)

方式二、key 值不受限制

from Crypto import Random
from Crypto.Cipher import AES
import base64
from hashlib import md5

def pad(data):
    length = 16 - (len(data) % 16)
    return data.encode(encoding='utf-8') + (chr(length)*length).encode(encoding='utf-8')

def unpad(data):
    return data[:-(data[-1] if type(data[-1]) == int else ord(data[-1]))]

def bytes_to_key(data, salt, output=48):
    data=data.encode(encoding='utf-8')
    assert len(salt) == 8, len(salt)
    data += salt
    key = md5(data).digest()
    final_key = key
    while len(final_key) < output:
        key = md5(key + data).digest()
        final_key += key
    return final_key[:output]

def encrypt(message, passphrase):
    salt = Random.new().read(8)
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    aes = AES.new(key, AES.MODE_CBC, iv)
    return base64.b64encode(b"Salted__" + salt + aes.encrypt(pad(message)))

def decrypt(encrypted, passphrase):
    encrypted = base64.b64decode(encrypted)
    assert encrypted[0:8] == b"Salted__"
    salt = encrypted[8:16]
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    aes = AES.new(key, AES.MODE_CBC, iv)
    return unpad(aes.decrypt(encrypted[16:]))

if __name__ == '__main__':

    key = 'seurtl23'
    data = 'oracless'
    encrypt_data = encrypt(data, key)
    print(encrypt_data)

    decrypt_data = decrypt(encrypt_data, key)
    print(decrypt_data)

对了,这个网站可以在线测试AES解密:http://www.bejson.com/enc/aesdes/

阅读量: | 柯西君_BingWong | 2020-06-13