AES:Advanced Encryption Standard,高级加密标准,是最常的对称加密算法。(加密和解密用相同的密钥)
简单记忆:C = E(K,P):明文P,密钥K,AES加密函数组成E,密文C。
AES是分组密码,即将明文分成一组一组的,每组长度相等,每次加密一组数据,直到整个加密完成。
AES分组的长度只能是128位,即分组为16个字节(每个字节8位),简单的说:明文P必须是长度为16的整数倍,字符串或数字。
密钥的长度可以使用128位、192位或256位,简单的说:密钥K可以是长度为16,24,32的字符串或数字。分别对应的加密轮数为10,12,14。
至于为什么会是这样呢?AES规范是这么写的。详细的解释见如下链接:
https://blog.csdn.net/qq_28205153/article/details/55798628,有图,有原理解析,这里就不啰嗦了。
AES只是基本算法,实现AES有几个模式:ECB、CBC、CFB、OFB,详细说明见如下链接:
https://blog.csdn.net/aaaaatiger/article/details/2525561
测试环境:win10 + Python3.5 + PyCrypto
推荐安装:pip install pycryptodome
PyCrypto支持DES、AES加密以及MD5、SHA各种HASH运算。这里使用CBC模式,即AES.new(key, AES.MODE_CBC,iv)函数,默认iv是16个0(这个称为初始化向量),由于是分组加密,所以下一组的iv,就用前一组的加密的密文来充当,指定IV来进行加解密,可以增加破解难度。(其他模式,例如:AES.new(key)、AES.new(key, AES.MODE_ECB))
注:记得将key,iv转换成:b"23143214",python3.x里默认的str是(py2.x里的)unicode,所以需要encode一下
# coding=utf-8
from Crypto.Cipher import AES
import json
import base64
import requests
import unittest
'''
AES加密接口测试
'''
class AESInterfaceTest(unittest.TestCase):
def setUp(self):
# 设置block_size的大小为16
self.bs = AES.block_size
# 对传入self.pad的内容自动补全16位,填充内容是“16-len(s)”对应的ascii字符
self.pad = lambda s: s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
self.unpad = lambda s: s[0:-ord(s[-1])]
# 待测接口地址
self.interface_url = "http://127.0.0.1:8000/api/user_list/"
# 密钥key需要与开发协商提供,或在接口文档中定义
key = 'DLsi60ewaW32ojd1'
self.key = key.encode('utf-8') # b"****"
self.iv = b"7683425105789011" # 可以自定义,也可以是随机值
self.mode = AES.MODE_CBC
def encrypt_base64(self, src):
'''
对密钥key进行加密,生成base64字符串
'''
return base64.urlsafe_b64decode(src)
def encrypt_aes(self, src, key, iv):
'''
生成AES密文
:param src: 明文P
:param key: 密钥K
:return:密文C
'''
cryptor = AES.new(key, self.mode, iv)
src_str = self.pad(src)
src_byte = src_str.encode('utf-8')
ciphertext = cryptor.encrypt(src_byte) # AES加密
aes_base64 = self.encrypt_base64(ciphertext) # 生成base64
print(aes_base64)
return aes_base64
def test_aes_interface(self):
'''测试加密接口'''
playload = {'user':'xxx', 'phone':''}
data = json.dumps(playload)
# 加密
encode_data = self.encrypt_aes(data, self.key, self.iv)
r = requests.post(self.interface_url, data={"data": encode_data})
result = r.text
print(result)
if __name__ == '__main__':
unittest.main()