crypto-js实现前端《AES/DES》加密,python进行对应的后端解密

最近学习爬虫在处理用户登录注册时,网站数据在传输时一般都是进行了加密处理后再传输的,因此想到对网站的登录操作进行加密,查阅资料找到了前端使用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的字符

分析
  1. 前端参数

    参数类型长度/bytes描述
    keyhex_str16加密秘钥
    ivhex_str16偏移量,采用key MD5加密获取
    datastr16n加密的数据,不足的根据padding来进行填充
    mode//加密方式
    padding//数据填充方式
  2. 前端逻辑分析

    1. key秘钥采用随机数生成16为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
    2. iv偏移量采用key进行MD5加密后取前16个字符作为偏移量
    3. AES加密后的数据最后再base64加密后显现的
    4. 数据传输时加密把key和加密后的数据传到后端
  3. 后端参数

    参数类型长度/bytes描述
    keystr16前端出来的加密秘钥
    ivstr16偏移量,采用key MD5加密后取前16位
    databytes/从前端传来的数据,通过base64解密后的
    mode//加密方式
    padding//数据填充方式
  4. 后端逻辑分析

    1. 拿到随机的key字符串,然后转化为MD5,取前面16个字符作为偏移量iv
    2. 将前端传来的加密数据先base64解密为需要AES解密的数据
    3. AES解密,key,iv都时字符串
    4. 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
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 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 "不存在此种数据填充方式"
在这里插入图片描述

2. DES加密解密

1. DES-128-CBC模式
分析
  1. 前端参数

    参数类型长度/bytes描述
    keyhex_str8加密秘钥
    ivhex_str8偏移量,采用key base64加密获取
    datastr16n加密的数据,不足的根据padding来进行填充
    mode//加密方式
    padding//数据填充方式
  2. 前端逻辑分析

    1. key秘钥采用随机数生成8为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
    2. iv偏移量采用key进行base64加密后取前8个字符作为偏移量
    3. DES加密后的数据最后再base64加密后显现的
    4. 数据传输时加密把key和加密后的数据传到后端
  3. 后端参数

    参数类型长度/bytes描述
    keystr8前端出来的加密秘钥
    ivstr8偏移量,采用key base64加密获取前面8位
    databytes/从前端传来的数据,通过base64解密后的
    mode//加密方式
    padding//数据填充方式
  4. 后端逻辑分析

    1. 拿到随机的key字符串,然后转化为base64,取前面8个字符作为偏移量iv
    2. 将前端传来的加密数据先base64解密为需要DES解密的数据
    3. DES解密,key,iv都时字符串
    4. 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
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();

}
后端解密
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 "不存在此种数据填充方式"
评论 2 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

山河长不高吖

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值