来源: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/