对称加密算法详解(DES篇):特点、实现与逆向实操
前言:前文我们讲解了哈希算法(MD5、SHA系列),这类算法属于"不可逆加密",仅用于数据校验、密码存储,无法还原原始数据。而对称加密算法属于"可逆加密",核心特点是加密和解密使用相同的密钥,具备速度快、效率高的优势,适合加密大量数据,是Web逆向、数据传输中最常用的加密方式之一。本文将围绕对称加密的核心认知展开,重点拆解DES算法的特点、关键概念、JS/Python实现,补充辨别技巧和应用场景
一、对称加密算法核心认知
对称加密算法(Symmetric Encryption Algorithm)是一种经典的加密技术,其核心逻辑是加密和解密使用相同的密钥(Secret Key):发送方使用密钥对明文进行加密,生成密文后传输;接收方使用相同的密钥对密文进行解密,还原为原始明文。
与哈希算法(不可逆)相比,对称加密的核心优势是"可逆性",可实现明文与密文的双向转换;与后续要讲解的非对称加密(如RSA)相比,其优势是加密解密速度快、效率高,适合处理大量数据(如文件加密、接口参数加密)。
常见的对称加密算法主要有3种:
-
DES(Data Encryption Standard):数据加密标准,早期主流对称加密算法,安全性较低,目前逐渐被淘汰,但仍是逆向学习的基础;
-
3DES(Triple DES):对数据执行3次DES加密,安全性高于DES,兼容DES密钥,用于老旧系统升级;
-
AES(Advanced Encryption Standard):高级加密标准,DES的替代算法,安全性高、效率高,是目前主流的对称加密算法。
本文重点讲解DES算法,后续将补充AES算法,帮助大家完整掌握对称加密的逆向思路。
二、DES算法详解(核心重点)
DES(数据加密标准)是最早的对称加密算法之一,由IBM公司设计,曾广泛应用于金融、通信等领域。虽然目前因安全性不足逐渐被AES替代,但作为对称加密的入门知识点,掌握DES的原理和实现,能更好地理解后续更复杂的对称加密逻辑(如AES),也是Web逆向中常见的基础加密类型。
2.1 DES核心关键词解析(必记)
在DES加密实现和逆向过程中,有4个核心关键词(key、iv、加密模式、填充模式),这也是所有对称加密算法(包括AES、3DES)的通用核心,必须理解其含义和作用,才能快速定位加密逻辑、破解加密参数。
2.1.1 密钥(key)
密钥是DES加密和解密的核心,也是对称加密的"核心钥匙"------加密和解密必须使用完全相同的密钥,否则无法还原明文。
DES对密钥有严格要求:密钥长度必须是8字节(64位),不足8字节会报错,超过8字节则会被截断(部分实现会直接报错)。例如:密钥"12345678"(8字节,符合要求)、"1234567"(7字节,不符合)、"123456789"(9字节,会被截断为前8字节)。
逆向场景中,密钥的获取是关键:部分网站会将密钥硬编码在前端代码中(可通过全局搜索"key""secret"等关键词找到);部分网站会通过接口动态获取密钥,需抓包分析密钥的请求和传输逻辑。
2.1.2 初始化向量(iv)
iv(Initialization Vector,初始化向量)是对称加密中用于增强安全性的随机值,核心作用是避免相同明文、相同密钥加密后得到相同的密文(防止攻击者通过密文规律破解明文)。
对于DES算法,iv有明确要求:仅在CBC加密模式下需要提供,ECB模式不需要iv;iv长度必须是8字节(与密钥长度一致),不足8字节会报错,超过8字节会被截断。
补充说明:iv是"随机辅助值",不需要保密(可公开),但必须与加密时使用的iv完全一致,否则解密会失败。例如:加密时使用iv"12345678",解密时必须使用相同的iv,哪怕密钥正确,iv错误也无法还原明文。
2.1.3 加密模式(核心)
DES加密时,会将明文按固定长度(8字节)分组,再对每组进行加密处理,加密模式决定了"分组之间如何关联",常用的有两种模式(ECB、CBC),其中CBC模式是目前最常用、最安全的模式。
1. ECB模式(电子密码本模式)
原理:将明文分成若干个8字节的分组,每个分组独立进行加密,分组之间没有关联;解密时,每个密文分组独立解密,再拼接得到明文。
特点:无需iv,实现简单、加密速度快;但安全性低------相同明文分组会生成相同密文分组,攻击者可通过密文规律破解明文(如重复的明文片段会产生重复的密文片段)。
适用场景:对安全性要求极低的场景(如简单文件加密),Web逆向中很少见。
2. CBC模式(密文分组链接模式)
原理:将明文分组与"前一个密文分组"进行异或运算后,再进行加密;第一个明文分组没有前一个密文分组,就与iv进行异或运算,再加密。解密时,每个密文分组解密后,与前一个密文分组(或iv)异或,得到明文分组。
特点:需要iv,安全性远高于ECB模式;相同明文、相同密钥,若iv不同,得到的密文也不同,能有效防止密文规律破解,是Web逆向、接口加密中最常用的DES加密模式。
2.1.4 填充模式
DES加密要求明文必须是"8字节的整数倍"(因为每个分组固定为8字节),若明文长度不是8字节的整数倍,就需要通过"填充"补足长度,填充模式决定了"如何补足字节"。
Web逆向中最常用的填充模式是PKCS#7(也是代码中默认使用的模式),其填充规则:不足8字节的部分,填充"需要补充的字节数"。例如:明文长度为5字节,需要补充3字节,就填充3个"0x03";明文长度为8字节,无需填充(或填充8个"0x08",解密时会自动识别并移除)。
补充:其他填充模式(如PKCS#5、ZeroPadding)在DES中较少使用,PKCS#7与PKCS#5在8字节分组的DES中效果一致,可通用。
2.2 DES的核心特点(含辨别技巧)
Web逆向中,快速辨别一段密文是否为DES加密,是提升效率的关键,结合DES的特性,总结以下特点和辨别方法:
-
密文格式 :DES加密的密文通常以Base64格式呈现(便于传输和存储),也可转为十六进制格式;密文长度不固定,与明文长度、填充模式相关,无固定长度限制(区别于哈希算法)。
-
核心标识:密文中若包含Base64特征字符(0-9、a-z、A-Z、+、/、=),且接口/代码中出现"des""key""iv""CBC""ECB""encrypt""decrypt"等关键词,大概率是DES加密。
-
密钥和iv特征:若代码中出现"8字节""64位"相关描述,且存在key和iv(CBC模式)的定义,优先判断为DES加密(AES的密钥和iv长度不同)。
-
可逆性:与哈希算法(不可逆)不同,DES加密是可逆的,只要拥有正确的key(和iv,CBC模式),就能解密密文得到明文(这是逆向DES的核心前提)。
-
安全性:DES的密钥长度仅64位(实际有效密钥56位),安全性较低,容易被暴力破解,目前已逐渐被AES替代,但在老旧系统、简单加密场景中仍有使用。
2.3 DES的JS/Python实现
DES加密的实现依赖工具库:前端常用crypto-js库,Python常用pycryptodome第三方库,以下给出完整实现代码(注释详细,新手可直接复制使用),与你提供的代码保持一致,补充关键说明和测试案例,贴合逆向实操需求。
2.3.1 前置准备(安装依赖库)
-
JS端:需安装
crypto-js库(与SHA、MD5实现共用,已安装可忽略),安装命令:npm install crypto-js; -
Python端:需安装
pycryptodome库,安装命令:pip install pycryptodome(用于提供DES加密、PKCS#7填充功能)。
2.3.2 JS实现(前端逆向常用)
封装DES加密、解密函数,采用CBC模式(最常用)、PKCS#7填充,支持明文与Base64密文的双向转换:
js
// 引用 crypto-js 加密模块(Node.js环境,浏览器端可通过script标签引入)
var CryptoJS = require('crypto-js');
// 创建 DES 加密解密对象(封装CBC模式,PKCS#7填充)
var DES = {
// 加密方法:明文 → Base64密文
encrypt: function (data, key, iv) {
// 1. 将key、iv、明文转为UTF-8格式的WordArray对象(crypto-js要求的格式)
var keyObj = CryptoJS.enc.Utf8.parse(key),
ivObj = CryptoJS.enc.Utf8.parse(iv),
srcsObj = CryptoJS.enc.Utf8.parse(data);
// 2. 执行DES加密:CBC模式、PKCS#7填充
var encrypted = CryptoJS.DES.encrypt(srcsObj, keyObj, {
iv: ivObj,
mode: CryptoJS.mode.CBC, // 常用模式
padding: CryptoJS.pad.Pkcs7 // 常用填充模式
});
// 3. 输出Base64格式的密文字符串(便于传输)
return encrypted.toString();
},
// 解密方法:Base64密文 → 明文
decrypt: function (data, key, iv) {
var keyObj = CryptoJS.enc.Utf8.parse(key),
ivObj = CryptoJS.enc.Utf8.parse(iv);
// 1. 执行DES解密,传入Base64密文、key、iv
var decrypted = CryptoJS.DES.decrypt(data, keyObj, {
iv: ivObj,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 2. 将解密结果转为UTF-8明文字符串
return decrypted.toString(CryptoJS.enc.Utf8);
},
}
// 测试案例(关键参数,必须符合要求)
var desKey = "12345678"; // 密钥:8字节,符合DES要求
var desIv = "12345678"; // 初始化向量:8字节,CBC模式必须提供
var text = "123456"; // 明文
// 加密
var encryptedData = DES.encrypt(text, desKey, desIv);
console.log("DES加密(Base64格式): ", encryptedData); // 输出示例:HUX+7VtHgb0=
// 解密
var decryptedData = DES.decrypt(encryptedData, desKey, desIv);
console.log("DES解密(明文): ", decryptedData); // 输出:123456
关键说明:
-
浏览器端使用时,无需安装npm包,直接通过
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>引入crypto-js库即可; -
若使用ECB模式,只需将
mode: CryptoJS.mode.CBC改为mode: CryptoJS.mode.ECB,且无需传入iv; -
密文格式可通过
encrypted.ciphertext.toString(CryptoJS.enc.Hex)改为十六进制,实际场景中Base64格式更常见。
2.3.3 Python实现(逆向脚本常用)
基于pycryptodome库,封装DES加密解密类,支持Base64格式的密文处理,与前端JS加密结果完全一致,适合编写逆向脚本、批量处理加密解密:
python
# 导入所需模块
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad # 提供PKCS#7填充/去填充
import base64
class DESCrypto:
def __init__(self, key, iv):
"""
初始化DES加密解密对象
:param key: 密钥(必须8字节)
:param iv: 初始化向量(CBC模式必须,8字节;ECB模式可忽略)
"""
# 确保key和iv为bytes格式,不足8字节报错,超过8字节截断
self.key = key if isinstance(key, bytes) else key.encode('utf-8')
self.iv = iv if isinstance(iv, bytes) else iv.encode('utf-8')
# 验证key和iv长度(必须8字节)
if len(self.key) != 8:
raise ValueError("DES密钥必须是8字节(64位)")
if len(self.iv) != 8:
raise ValueError("DES初始化向量(iv)必须是8字节(64位)")
def encrypt(self, plaintext):
"""
加密明文,返回Base64格式密文
:param plaintext: 明文(字符串)
:return: Base64编码的密文字符串
"""
# 1. 创建DES对象,使用CBC模式
cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
# 2. PKCS#7填充,确保明文长度是8字节的整数倍
padded_data = pad(plaintext.encode('utf-8'), DES.block_size)
# 3. 加密,得到bytes类型密文
encrypted = cipher.encrypt(padded_data)
# 4. Base64编码,转为字符串(便于传输和存储)
return base64.b64encode(encrypted).decode('utf-8')
def decrypt(self, ciphertext):
"""
解密密文,返回明文
:param ciphertext: Base64格式的密文字符串
:return: 明文(字符串)
"""
# 1. Base64解码,得到bytes类型密文
encrypted_data = base64.b64decode(ciphertext)
# 2. 创建DES对象,CBC模式
cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
# 3. 解密,得到bytes类型明文(含填充)
decrypted = cipher.decrypt(encrypted_data)
# 4. 去除PKCS#7填充,解码为字符串
return unpad(decrypted, DES.block_size).decode('utf-8')
# 测试案例
if __name__ == '__main__':
# 初始化DES对象(key和iv均为8字节,符合要求)
des = DESCrypto("12345678", "12345678")
# 加密
encrypt_result = des.encrypt('123456')
print("DES加密(Base64格式):", encrypt_result) # 输出:HUX+7VtHgb0=(与JS加密结果一致)
# 解密
decrypt_result = des.decrypt(encrypt_result)
print("DES解密(明文):", decrypt_result) # 输出:123456
# 测试解密已知密文(与JS测试案例对应)
print(des.decrypt('HUX+7VtHgb0=')) # 输出:123456
关键说明:
-
若使用ECB模式,初始化DES对象时改为
DES.new(self.key, DES.MODE_ECB),且无需传入iv; -
pad函数的第二个参数
DES.block_size固定为8,对应DES的分组长度; -
必须确保key和iv为8字节,否则会抛出异常,这是DES加密的硬性要求。
三、DES逆向实操思路
Web逆向中,DES加密的逆向核心是"找到key和iv(CBC模式)",再模拟加密解密逻辑,以下是具体步骤:
-
抓包判断:抓包获取接口的请求/响应参数,若密文为Base64格式(含+、/、=),且接口代码中出现"des""key""iv"等关键词,初步判断为DES加密;
-
定位加密位置 :全局搜索关键词
des、encrypt、decrypt、key、iv,找到加密函数(通常是一个包含DES、key、iv的函数); -
提取关键参数:从加密函数中提取key和iv(注意长度是否为8字节),记录加密模式(CBC/ECB)和填充模式(通常是PKCS#7);
-
验证加密逻辑:用本文提供的JS/Python代码,使用提取到的key、iv,模拟加密明文,对比抓包得到的密文,确认参数和模式正确;
-
编写逆向脚本:用Python封装DES加密解密函数,传入提取到的key和iv,批量生成密文(用于模拟请求)或解密密文(用于分析接口参数)。
示例:若某接口的密码参数采用DES加密(CBC模式,key="abcdefgh",iv="87654321"),则可通过Python脚本加密明文密码,生成符合要求的密文,用于模拟登录请求。
四、常见问题与注意事项
-
误区1:密钥长度可以随意设置:DES的密钥必须是8字节(64位),不足8字节会报错,超过8字节会被截断,这是DES的硬性要求,无法修改。
-
误区2:iv需要保密:iv是辅助加密的随机值,无需保密,可公开传输,但必须与加密时的iv完全一致,否则解密失败。
-
问题3:JS和Python加密结果不一致:大概率是3种情况:① key/iv的编码不一致(需统一为UTF-8);② 加密模式/填充模式不同;③ 密文格式不同(JS默认Base64,Python需手动Base64编码)。
-
问题4:找不到key和iv:部分网站会将key和iv拼接在请求参数中、或通过接口动态返回、或硬编码在前端JS文件中(可通过搜索"8字节字符串"定位)。
-
注意:DES的安全性局限:DES的密钥长度较短,容易被暴力破解,目前高安全性场景(如金融、支付)已不再使用DES,而是采用AES加密,后续将详细讲解AES算法。
五、总结
本文详细拆解了对称加密的核心概念,重点讲解了DES算法的关键参数、特点、辨别技巧和完整实现,补充了逆向实操思路,与前文哈希算法(MD5、SHA)的讲解节奏、风格保持一致,覆盖新手从入门到逆向实操的全部需求。
DES作为对称加密的基础,掌握其原理和实现,能为后续学习更复杂的AES加密打下坚实基础。后续我会持续更新AES算法、非对称加密(RSA)以及更多逆向实战案例,每篇文章都会搭配详细的代码、实操步骤和避坑技巧,新手可直接跟着实操,快速提升逆向能力。
关注我,每天学习一个逆向小知识点,从新手成长为逆向高手!