前言:DES 属于老旧对称加密算法 ,密钥长度仅 56bit,安全性弱,现在不推荐用于正式生产环境,仅用于对接老旧系统、爬虫逆向、兼容老接口。新项目优先 AES-GCM/AES-CBC。
浏览器原生 Web Crypto API 不直接支持 DES ,所以 JS 里实现 DES 基本都依赖
CryptoJS。
一、DES 基础概念
DES(Data Encryption Standard,数据加密标准),对称加密:加密、解密使用同一个密钥。
- 分组大小:64bit(8字节)
- 有效密钥:56bit(输入密钥通常传 8 字节 64bit,其中8bit是奇偶校验位,会被忽略)
- 常见模式:
ECB、CBC(最常用) - 填充方式:
Pkcs7(CryptoJS 默认) - 缺点:密钥太短,暴力破解成本低,已经被淘汰
- 3DES(TripleDES):DES 三次加密,密钥更长,安全性比 DES 高一点,老接口也经常见到
重点区分:
- ECB:电子密码本,无 IV(偏移向量),相同明文+密钥加密结果一样,不安全,不推荐
- CBC:密码分组链接,需要 IV,每个分组依赖上一组密文,更常用
二、CryptoJS 引入
浏览器直接 CDN 引入,Node.js 可以 npm 安装
<!-- 浏览器 -->
<script src="[https://cdn.jsdelivr.net/npm/crypto-js@4.2.0/crypto-js.min.js](https://cdn.jsdelivr.net/npm/crypto-js@4.2.0/crypto-js.min.js)"></script>
# Node.js
npm install crypto-js
// Node 引入
const CryptoJS = require("crypto-js");
三、DES-CBC 完整示例(最常用,和Java/PHP老系统互通)
约定:
-
key:8字节字符串(DES固定8字节!超过会截断,不足会补0)
-
iv:8字节字符串(CBC模式必须,同样固定8字节)
-
输出:base64(后端接口最常见)
-
编码:UTF8
/**
- DES-CBC 加密
- @param {string} plainText 明文
- @param {string} key 密钥 8位
- @param {string} iv 偏移量 8位
- @returns {string} base64密文
*/
function desEncryptCBC(plainText, key, iv) {
const keyWord = CryptoJS.enc.Utf8.parse(key);
const ivWord = CryptoJS.enc.Utf8.parse(iv);
const encrypted = CryptoJS.DES.encrypt(plainText, keyWord, {
iv: ivWord,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
/**
- DES-CBC 解密
- @param {string} cipherText base64密文
- @param {string} key 密钥 8位
- @param {string} iv 偏移量 8位
- @returns {string} 明文
*/
function desDecryptCBC(cipherText, key, iv) {
const keyWord = CryptoJS.enc.Utf8.parse(key);
const ivWord = CryptoJS.enc.Utf8.parse(iv);
const decrypted = CryptoJS.DES.decrypt(cipherText, keyWord, {
iv: ivWord,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
// 测试
const text = "hello des test";
const key = "12345678"; // 必须8字节
const iv = "87654321"; // 必须8字节
const cipher = desEncryptCBC(text, key, iv);
console.log("密文:", cipher);
const origin = desDecryptCBC(cipher, key, iv);
console.log("解密:", origin);
四、DES-ECB 示例(无IV,老旧接口偶尔遇到)
⚠️ ECB 不安全,仅兼容老系统使用,新项目禁止
function desEncryptECB(plainText, key) {
const keyWord = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.DES.encrypt(plainText, keyWord, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
function desDecryptECB(cipherText, key) {
const keyWord = CryptoJS.enc.Utf8.parse(key);
const decrypted = CryptoJS.DES.decrypt(cipherText, keyWord, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
五、3DES(TripleDES / DES-EDE3)补充
很多老Java接口是3DES,CryptoJS 同样支持,只是调用方法变成 CryptoJS.TripleDES
3DES 密钥要求:24字节(192bit)
function tripleDesEncrypt(plainText, key, iv) {
const keyWord = CryptoJS.enc.Utf8.parse(key);
const ivWord = CryptoJS.enc.Utf8.parse(iv);
const encrypted = CryptoJS.TripleDES.encrypt(plainText, keyWord, {
iv: ivWord,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
六、常见踩坑点(逆向对接高频问题)
-
密钥、IV长度不对
DES 硬性要求 8字节,3DES 24字节。很多人传16位key,直接报错或者和后端对不上。 -
编码不一致
后端是 GBK,前端是 UTF8,结果一定对不上。CryptoJS 默认 Utf8,如果后端GBK,需要额外编码库转GBK。 -
填充模式不匹配
Java 常见Pkcs5Padding,在 CryptoJS 里等价于Pkcs7,可以互通;如果是 NoPadding,需要自己手动补位。 -
输出格式
有的后端要 hex 十六进制,不是 base64:// 输出hex
return encrypted.ciphertext.toString(CryptoJS.enc.Hex); -
Web Crypto 原生不支持DES
浏览器标准 Web Crypto API 算法列表没有 DES/3DES,这也是为什么逆向里几乎全部看到 CryptoJS 实现 DES。 -
大小写、换行
部分后端校验严格,base64 里的+ / =不要被url编码自动转义,爬虫请求时注意。
七、安全建议
- DES 密钥太短,不适合互联网公网业务,只用于对接遗留老系统;
- 优先迁移 AES-CBC / AES-GCM;
- 如果必须用DES,不要用ECB模式,统一CBC,IV随机生成并随密文传给后端;
- 前端任何加密都不能当成安全屏障,前端密钥容易被逆向扒出来,仅做传输兼容,不能防恶意抓包。
八、逆向小提示
爬虫逆向遇到 DES 加密特征:
- 搜索代码关键词:
CryptoJS.DES、CryptoJS.TripleDES - 模式:
CBC/ECB - 固定8位key、8位iv,是很明显的DES特征
- 很多老网站、老政务、老ERP接口喜欢用DES