最近学习爬虫在处理用户登录注册时,网站数据在传输时一般都是进行了加密处理后再传输的,因此想到对网站的登录操作进行加密,查阅资料找到了前端使用crypto-js来进行加密,后端使用python对应的解密方式反向解密。后续慢慢一个一个的加密方式补充。
一、对称加密AES、DES
1. AES加密解密
1.AES-128-CBC
Zero:数据长度不足时填充0,如果数据长度刚好合适就不填充
PKCS5:填充8字节长度的ASCII码编号为8的字符
PKCS7:(1) 数据如果长度刚好合适,就填充数据长度的字节,填充数据为ASCII码编号为数据长度的字符
(2)数据长度如果没对齐,则差n长度,就补充n长度的ASCII码编号为n的字符
分析
-
前端参数
参数 类型 长度/bytes 描述 key hex_str 16 加密秘钥 iv hex_str 16 偏移量,采用key MD5加密获取 data str 16n 加密的数据,不足的根据padding来进行填充 mode / / 加密方式 padding / / 数据填充方式 -
前端逻辑分析
- key秘钥采用随机数生成16为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
- iv偏移量采用key进行MD5加密后取前16个字符作为偏移量
- AES加密后的数据最后再base64加密后显现的
- 数据传输时加密把key和加密后的数据传到后端
-
后端参数
参数 类型 长度/bytes 描述 key str 16 前端出来的加密秘钥 iv str 16 偏移量,采用key MD5加密后取前16位 data bytes / 从前端传来的数据,通过base64解密后的 mode / / 加密方式 padding / / 数据填充方式 -
后端逻辑分析
- 拿到随机的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()
}
后端解密
import base64
import