最近学习爬虫在处理用户登录注册时,网站数据在传输时一般都是进行了加密处理后再传输的,因此想到对网站的登录操作进行加密,查阅资料找到了前端使用crypto-js来进行加密,后端使用python对应的解密方式反向解密。后续慢慢一个一个的加密方式补充。
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 | / | / | 数据填充方式 |
前端逻辑分析
后端参数
参数 | 类型 | 长度/bytes | 描述 |
---|---|---|---|
key | str | 16 | 前端出来的加密秘钥 |
iv | str | 16 | 偏移量,采用key MD5加密后取前16位 |
data | bytes | / | 从前端传来的数据,通过base64解密后的 |
mode | / | / | 加密方式 |
padding | / | / | 数据填充方式 |
后端逻辑分析
// 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.toSting()
}
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 "不存在此种数据填充方式"
前端参数
参数 | 类型 | 长度/bytes | 描述 |
---|---|---|---|
key | hex_str | 8 | 加密秘钥 |
iv | hex_str | 8 | 偏移量,采用key base64加密获取 |
data | str | 16n | 加密的数据,不足的根据padding来进行填充 |
mode | / | / | 加密方式 |
padding | / | / | 数据填充方式 |
前端逻辑分析
后端参数
参数 | 类型 | 长度/bytes | 描述 |
---|---|---|---|
key | str | 8 | 前端出来的加密秘钥 |
iv | str | 8 | 偏移量,采用key base64加密获取前面8位 |
data | bytes | / | 从前端传来的数据,通过base64解密后的 |
mode | / | / | 加密方式 |
padding | / | / | 数据填充方式 |
后端逻辑分析
// 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();
}
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 "不存在此种数据填充方式"