一. AES加密解密
1.AES-128-CBC
Zero:数据长度不足时填充0,如果数据长度刚好合适就不填充
PKCS5:填充8字节长度的ASCII码编号为8的字符
PKCS7:(1) 数据如果长度刚好合适,就填充数据长度的字节,填充数据为ASCII码编号为数据长度的字符
(2)数据长度如果没对齐,则差n长度,就补充n长度的ASCII码编号为n的字符
分析
1.前端参数
2.前端逻辑分析
- key秘钥采用随机数生成16为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
- iv偏移量采用key进行MD5加密后取前16个字符作为偏移量
- AES加密后的数据最后再base64加密后显现的
- 数据传输时加密把key和加密后的数据传到后端
3.后端参数
4.后端逻辑分析
- 拿到随机的key字符串,然后转化为MD5,取前面16个字符作为偏移量iv
- 将前端传来的加密数据先base64解密为需要AES解密的数据
- AES解密,key,iv都时字符串
- 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
js前端实现加密 // n位随机数生成 function randomNum(n) { let sString = ""; let strings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; for (i = 0; i < n; i++) { ind = Math.floor(Math.random() * strings.length); sString += strings.charAt(ind); } return sString } //AES-128-CBC-ZeroPadding加密 function encrypt(data, key) { iv = CryptoJS.MD5(key).toString().substring(0, 16); //取转化为md5格式的前面16位字符 key = CryptoJS.enc.Utf8.parse(key); //解析后的key iv = CryptoJS.enc.Utf8.parse(iv); //解析后的iv encrypted = CryptoJS.AES.encrypt(data, key, { //j加密 iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); return encrypted.toString() } python后端解密 import base64 import hashlib from Crypto.Cipher import AES, DES class DeAesCrypt: """ AES-128-CBC解密 """ def __init__(self, data, key, pad): """ :param data: 加密后的字符串 :param key: 随机的16位字符 :param pad: 填充方式 """ self.key = key self.data = data self.pad = pad.lower() hash_obj = hashlib.md5() # 构造md5对象 hash_obj.update(key.encode()) # 进行md5加密,md5只能对byte类型进行加密 res_md5 = hash_obj.hexdigest() # 获取加密后的字符串数据 self.iv = res_md5[:16] @property def decrypt_aes(self): """AES-128-CBC解密""" real_data = base64.b64decode(self.data) my_aes = AES.new(self.key, AES.MODE_CBC, self.iv) decrypt_data = my_aes.decrypt(real_data) return self.get_str(decrypt_data) def get_str(self, bd): """解密后的数据去除加密前添加的数据""" if self.pad == "zero": # 去掉数据在转化前不足16位长度时添加的ASCII码为0编号的二进制字符 return ''.join([chr(i) for i in bd if i != 0 ]) elif self.pad == "pkcs7": # 去掉pkcs7模式中添加后面的字符 return ''.join([chr(i) for i in i > 32]) # 此处报错,在我环境 else: return "不存在此种数据填充方式"
二、 DES加密解密
1.DES-128-CBC模式
分析
1)前端参数
2)前端逻辑分析
- key秘钥采用随机数生成8为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
- iv偏移量采用key进行base64加密后取前8个字符作为偏移量
- DES加密后的数据最后再base64加密后显现的
- 数据传输时加密把key和加密后的数据传到后端
3)后端参数
4.后端逻辑分析
- 拿到随机的key字符串,然后转化为base64,取前面8个字符作为偏移量iv
- 将前端传来的加密数据先base64解密为需要DES解密的数据
- DES解密,key,iv都时字符串
- 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
js前端实现加密 // n位随机数生成 function randomNum(n) { let sString = ""; let strings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; for (i = 0; i < n; i++) { ind = Math.floor(Math.random() * strings.length); sString += strings.charAt(ind); } return sString } // DES-128-CBC-Zero-crypt function desZeroEncrypt(data, key) { let iv = CryptoJS.enc.Utf8.parse(key); iv = CryptoJS.enc.Base64.stringify(iv).toString().substring(0,8);//base64加密取前8位 iv = CryptoJS.enc.Utf8.parse(iv); key = CryptoJS.enc.Utf8.parse(key); return CryptoJS.DES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }).toString(); } python 后端解密 import base64 import hashlib from Crypto.Cipher import AES, DES class DeDesCrypt: """ DES-128-CBC解密 """ def __init__(self, data, key, pad): """ :param data: 加密后的字符串,在解密是需要先进行base64解密后才行 :param key: 随机的8位字符 :param pad: 填充方式 """ self.key = key self.data = base64.b64decode(data.encode()) self.pad = pad.lower() self.iv = base64.b64encode(key.encode())[0:8] @property def decrypt_des(self): """DES-128-CBC解密""" my_des = DES.new(self.key, AES.MODE_CBC, self.iv) decrypt_data = my_des.decrypt(self.data) return self.get_str(decrypt_data) def get_str(self, bd): """解密后的数据去除加密前添加的数据""" if self.pad == "zero": # 去掉数据在转化前不足8位长度时添加的ASCII码为0编号的二进制字符 return ''.join([chr(i) for i in bd if i != 0]) elif self.pad == "pkcs7": # 去掉pkcs7模式中添加后面的字符 return ''.join([chr(i) for i in i > 32]) else: return "不存在此种数据填充方式"
转载原文链接:https://blog.csdn.net/hl120841/article/details/105278277