DES、AES、RSA 加密算法详解(含 JS/Python 实现 + 逆向实战案例)

对称加密算法是一种加密技术,其核心特点是加密和解密使用相同的密钥,即发送方用密钥加密明文,接收方用相同密钥解密密文。这类算法速度快、效率高,适合加密大量数据。

常见的对称加密算法有:

  • DES(Data Encryption Standard),翻译为中文称为 数据加密标准

  • 3DES(Triple DES):对数据执行3次DES加密,相对于 DES 更加安全。

  • AES(Advanced Encryption Standard):翻译为中文为 高级加密标准,是 DES 的替代算法。

我们主要讲解 DES 和 AES 加密算法。

4.1 DES

4.1.1 DES 实现

  • js 实现
js 复制代码
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js');

// 创建 DES 对象
var DES = {
    // 加密方法
    encrypt: function (data, key, iv) {
        // 转为 UTF-8 格式的 WordArray 对象供 DES 算法使用
        var key = CryptoJS.enc.Utf8.parse(key),
            iv = CryptoJS.enc.Utf8.parse(iv),
            srcs = CryptoJS.enc.Utf8.parse(data),
            // 使用 DES 加密
            encrypted = CryptoJS.DES.encrypt(srcs, key, {
                iv: iv,
                // CBC 加密模式,需添加初始向量(IV)增强安全性
                mode: CryptoJS.mode.CBC,
                // Pkcs7 填充方式,自动补足数据块至 8 字节倍数
                padding: CryptoJS.pad.Pkcs7
            });
        // 输出为 Base64 编码的密文字符串
        return encrypted.toString();
    },
    // 解密方法
    decrypt: function (data, key, iv) {
        var key = CryptoJS.enc.Utf8.parse(key),
            iv = CryptoJS.enc.Utf8.parse(iv),
            decrypted = CryptoJS.DES.decrypt(data, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });
        // 转换为明文字符串
        return decrypted.toString(CryptoJS.enc.Utf8);
    },
}

// 密钥
var desKey = "12345678";
// 初始向量
var desIv = "12345678";
// 明文内容
var text = "123456";

// 加密
var encryptedData = DES.encrypt(text, desKey, desIv);
console.log("加密字符串: ", encryptedData);
// 解密
var decryptedData = DES.decrypt(encryptedData, desKey, desIv);
console.log("解密字符串: ", decryptedData);
  • python 实现

python 想要实现 DES 加密算法,需要安装第三方库:pip install pycryptodome

python 复制代码
# 提供 DES 加密算法
from Crypto.Cipher import DES
# 提供 PKCS#7 填充
from Crypto.Util.Padding import pad, unpad
import base64


class DESCrypto:
    def __init__(self, key, iv):
        # 接收字节密钥和IV,自动转换为bytes格式
        self.key = key if isinstance(key, bytes) else key.encode('utf-8')
        self.iv = iv if isinstance(iv, bytes) else iv.encode('utf-8')

    def encrypt(self, plaintext):
        """加密明文并返回Base64编码结果"""
        # 创建 DES 对象,使用 CBC 模式
        cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
        # 对明文的处理,使用 PKCS#7 方式填充,确保数据长度是 8 字节的倍数
        padded_data = pad(plaintext.encode('utf-8'), DES.block_size)
        # 加密
        encrypted = cipher.encrypt(padded_data)
        # 返回 Base64 字符串
        return base64.b64encode(encrypted).decode('utf-8')

    def decrypt(self, ciphertext):
        """解密Base64编码的密文"""
        # 创建 DES 对象,使用 CBC 模式
        cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
        # 对明文使用 Base64 解码
        encrypted_data = base64.b64decode(ciphertext)
        # 解密
        decrypted = cipher.decrypt(encrypted_data)
        # 移除 PKCS#7 填充并解码为字符串
        return unpad(decrypted, DES.block_size).decode('utf-8')


if __name__ == '__main__':
    des = DESCrypto("12345678", "12345678")
    print(des.encrypt('123456'))
    print(des.decrypt('HUX+7VtHgb0='))

不论是 JavaScript 代码实现,还是 python 代码实现,我们都可以看到几个关键词:key(密钥)、iv(初始化向量)、加密模式、填充模式,这些是DES和AES加密中都存在的核心要素,也是对称加密算法的主要特点。

4.1.2 DES 特点

1)iv

当我们使用 CBC 模式实现加密的时候,需要提供一个初始化向量 iv,iv 必须是 8 字节。iv的核心作用是增强加密安全性,避免相同明文和密钥加密出相同密文,具体需结合加密模式理解。

2)加密模式

DES常用两种加密模式,分别是 ECB 和 CBC:

ECB:全称 Electronic Codebook(电子密码本模式),每个数据块独立加密解密,无需iv,实现简单但安全性极低,仅适用于非敏感数据临时加密。

CBC:全称 Cipher Block Chaining(密文分组链接模式),核心是明文分组与前一个密文分组(或iv)异或后再加密,安全性远高于ECB,是主流使用模式。

3)填充模式

DES要求明文按8字节分组,若明文长度不是8字节整数倍,需通过填充补足。常用PKCS#7填充模式,规则为:不足部分填充"需要补充的字节数"。

4)其他特点
  1. 密文可表现为十六进制或base64格式,日常开发中base64格式更常用;2. 核心关键字:des、key、iv、CBC、ECB、encrypt、decrypt。

4.1.3 案例 - 长安

1)需求:网址https://bqcm0.cavip1.com/,接口https://bqcm0.cavip1.com/wps/session/login,逆向表单参数(整体为密文,无法直接全局搜索定位)。

2)逆向步骤:

① 调用堆栈调试:从调用堆栈中找到login函数(推测为登录相关),打上断点后重新运行程序,可成功断住。

② 查看数据:断点处a的值为明文参数{username: 'z13800138000', password: '123456', captcha: '6'},i的值为密钥相关参数。

③ 分析加密函数:进入utils.desEncrypt函数,可见其使用CryptoJS实现DES加密,且为ECB模式、Pkcs7填充,确认该接口表单参数采用DES-ECB加密。

js 复制代码
desEncrypt: function(e, t) {
    var n = CryptoJS.enc.Utf8.parse(t);
    return CryptoJS.DES.encrypt(e, n, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    }).toString()
},

4.2 AES

4.2.1 AES 特点

AES是DES的替代算法,安全性更高,实现原理和代码与DES类似,核心区别在于密钥和iv长度:

  • 密钥长度可选:128位(16字节)、192位(24字节)、256位(32字节);

  • iv固定为128位(16字节)。

4.2.2 AES 实现

  • js 实现
js 复制代码
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js');

var AES = {
    encrypt: function (data, key, iv) {
        // 转为 UTF-8 格式的 WordArray 对象供 AES 算法使用
        var key = CryptoJS.enc.Utf8.parse(key),
            iv = CryptoJS.enc.Utf8.parse(iv),
            srcs = CryptoJS.enc.Utf8.parse(data),
            // 使用 AES 加密
            encrypted = CryptoJS.AES.encrypt(srcs, key, {
                iv: iv,
                // CBC 加密模式,需添加初始向量(IV)增强安全性
                mode: CryptoJS.mode.CBC,
                // Pkcs7 填充方式,自动补足数据块至 8 字节倍数
                padding: CryptoJS.pad.Pkcs7
            });
        // 输出为 Base64 编码的密文字符串
        return encrypted.toString();
    },
    decrypt: function (data, key, iv) {
        var key = CryptoJS.enc.Utf8.parse(key),
            iv = CryptoJS.enc.Utf8.parse(iv),
            decrypted = CryptoJS.AES.decrypt(data, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });
        // 转换为明文字符串
        return decrypted.toString(CryptoJS.enc.Utf8);
    },
}

// 密钥
var aesKey = "0123456789abcdef";
// 初始向量
var aesIv = "0123456789abcdef";
// 明文内容
var text = "123456";

// 加密
var encryptedData = AES.encrypt(text, aesKey, aesIv);
console.log("加密字符串: ", encryptedData);
// 解密
var decryptedData = AES.decrypt(encryptedData, aesKey, aesIv);
console.log("解密字符串: ", decryptedData);
  • python 实现
python 复制代码
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

class AESCrypto:
    def __init__(self, key, iv):
        # 接收字节密钥和IV,自动转换为bytes格式
        self.key = key if isinstance(key, bytes) else key.encode('utf-8')
        self.iv = iv if isinstance(iv, bytes) else iv.encode('utf-8')
          
    def encrypt(self, plaintext):
        """加密明文并返回Base64编码结果"""
        # 创建 AES 对象,使用 CBC 模式
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        # 对明文的处理,使用 PKCS#7 方式填充,确保数据长度是 8 字节的倍数
        padded_data = pad(plaintext.encode('utf-8'), AES.block_size)
        # 加密
        encrypted = cipher.encrypt(padded_data)
        # 返回 Base64 字符串
        return base64.b64encode(encrypted).decode('utf-8')
    
    def decrypt(self, ciphertext):
        """解密Base64编码的密文"""
        # 创建 AES 对象,使用 CBC 模式
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        # 对明文使用 Base64 解码
        encrypted_data = base64.b64decode(ciphertext)
        # 解密
        decrypted = cipher.decrypt(encrypted_data)
        # 移除 PKCS#7 填充并解码为字符串
        return unpad(decrypted, AES.block_size).decode('utf-8')

if __name__ == '__main__':
    aes = AESCrypto("0123456789abcdef", "0123456789abcdef")
    print(aes.encrypt('123456'))
    print(aes.decrypt('AL5riQzgwmMhXZX+5MtU0A=='))

4.2.3 案例 - 学习通

1)需求:网址https://passport2.chaoxing.com/login,接口https://passport2.chaoxing.com/fanyalogin,逆向password参数(密文示例:0QgUbMUJj2usHikiqtb8HQ==)。

2)逆向步骤:

① 定位加密位置:全局搜索'password':,快速找到password参数的加密位置。

② 分析加密函数:查看encryptByAES函数,可见其使用CryptoJS实现AES加密,采用CBC模式、Pkcs7填充,密钥与iv相同,确认password参数采用AES-CBC加密。

js 复制代码
function encryptByAES(message, key) {
    let CBCOptions = {
        iv: CryptoJS.enc.Utf8.parse(key),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    };
    let aeskey = CryptoJS.enc.Utf8.parse(key);
    let secretData = CryptoJS.enc.Utf8.parse(message);
    let encrypted = CryptoJS.AES.encrypt(
        secretData,
        aeskey,
        CBCOptions
    );
    return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}

5 非对称算法 - RSA

非对称加密,使用 一对密钥(公钥和私钥)进行加密和解密。与对称加密不同,非对称加密的加密和解密使用不同的密钥,解决了密钥分发问题,但计算速度较慢,所以一般不会用非对称加密算法对大量数据进行加密。

5.1 RSA 特点

  1. 长度:rsa 的密文与密钥的长度有关,密钥长度越长,密文长度越长;密钥长度可选择1024位、2048位和4096位。

  2. 内容:对相同的明文加密,密文都会不同。

  3. 关键字:key、new RSA、setPublic、encrypt、decrypt。

5.2 RSA 实现

  • js 实现(需安装node-jsencrypt库:npm install node-jsencrypt
js 复制代码
const fs = require('fs');
const JSEncrypt = require('node-jsencrypt');

var RSA = {
    encrypt: function (data, key) {
        // 创建 JSEncrypt 对象
        const encryptor = new JSEncrypt();
        // 设置公钥
        encryptor.setPublicKey(key);
        // 加密数据
        return encryptor.encrypt(data);
    },
    decrypt: function (data, key) {
        // 创建 JSEncrypt 对象
        const decryptor = new JSEncrypt();
        // 设置私钥
        decryptor.setPrivateKey(key);
        // 解密数据
        return decryptor.decrypt(data);
    }
}

// 加密
const publicKey = fs.readFileSync('public_key.pem', 'utf8');
var encryptedData = RSA.encrypt("123456", publicKey);
console.log(encryptedData);

// 解密
const privateKey = fs.readFileSync('private_key.pem', 'utf8');
var decryptedData = RSA.decrypt(encryptedData, privateKey);
console.log(decryptedData);
  • python 实现(需安装rsa库:pip install rsa
python 复制代码
import rsa
import base64

class RSA:
    def __init__(self, publicKey, private_key):
        self.publicKey = publicKey
        self.private_key = private_key

    def encrypt(self, t):
        """公钥加密"""
        encrypted = rsa.encrypt(t.encode("utf-8"), self.publicKey)
        return base64.b64encode(encrypted).decode("utf-8")

    def decrypt(self, t):
        """私钥解密"""
        return rsa.decrypt(base64.b64decode(t), self.private_key).decode("utf-8")

if __name__ == "__main__":
    # 生成公钥、私钥
    public_key, private_key = rsa.newkeys(512)
    print('公钥:', public_key)
    print('私钥:', private_key)

    # 创建 rsa 对象
    rsa_ = RSA(public_key, private_key)
    # 待加密字符串
    text = '123456'
    encrypted_str = rsa_.encrypt(text)
    print('加密字符串:', encrypted_str)
    decrypted_str = rsa_.decrypt(encrypted_str)
    print('解密字符串:', decrypted_str)

5.3 案例 - 新华保险

1)需求:网址https://tms.newchinalife.com/ex//app/login/login.jsp,接口https://tms.newchinalife.com/ex/j_spring_security_check,逆向j_password参数(密文示例:n4NUSQ479nvK9xjCq5W2MesLXPWfJ/mGdTENn8ptJr666++5C0w5pO1forQOTXOkFdwC1/TdoxQLJXhwGGDZwQg331AIPrjdLJZjTjiWjKVTRUKua8eOIVX4u2421PSjNbXILrALrRxhwKE4LjLwt8VCeFXF2yGA8lMOXOKPNNelbZOUo/eSNSBdIAHEqWZxBQiWCX6s7FAp5T5DH0a/yd+LtgbfRCaprKvH3G7oreW8HzJKJkp3cKrF2o9ntgaws2UJlF+3rTapAa5f8Jo4KJmDHXYH7bY2fSKvjSBZxv26/ZZaPEM4llrCcm3y6+/Kuks+EElCIYf1Sjtg8HQr1A==)。

2)逆向步骤:

① 定位加密位置:全局搜索j_password,结果较少且可找到相关数据,直接定位到加密位置。

② 断点验证:重新发送请求,断点成功断住,查看j_pwd参数为密码明文,推测此处为加密入口。

③ 分析加密函数:进入rasClient.encrypt函数,可见RSAClient对象调用setPublicKey方法,公钥值为PUBLICKEY,确认j_password参数采用RSA加密。

以上就是对称加密(DES、AES)和非对称加密(RSA)的核心内容,包含实现代码、核心特点和真实逆向案例,覆盖日常开发和逆向实操的核心需求,可直接对照代码和案例上手练习。

关注我,解锁更多加密算法、逆向实战技巧!

相关推荐
漂流瓶jz2 小时前
总结CSS组件化演进之路:命名规范/CSS Modules/CSS in JS/原子化CSS
前端·javascript·css
踩着两条虫3 小时前
「AI + 低代码」的可视化设计器
开发语言·前端·低代码·设计模式·架构
Jagger_3 小时前
项目上线忙碌结束之后,为什么总想找点事做?
前端
scan7243 小时前
智能体多个工具调用
python
2401_867623983 小时前
CSS Flex布局中如何设置子元素间距_掌握gap属性的现代用法
jvm·数据库·python
GalenZhang8883 小时前
OpenClaw 配置多个飞书账号实战指南
前端·chrome·飞书·openclaw
即使再小的船也能远航3 小时前
【Python】安装
开发语言·python
weixin_421725263 小时前
Linux 编程语言全解析:C、C++、Python、Go、Rust 谁更强?
linux·python·go·c·编程语言
没有梦想的咸鱼185-1037-16634 小时前
AI-Python机器学习、深度学习核心技术与前沿应用及OpenClaw、Hermes自动化编程
人工智能·python·深度学习·机器学习·chatgpt·数据挖掘·数据分析
steven~~~4 小时前
为什么mq报错
javascript