文章目录
一、对称加密介绍
DES属于对称加密算法,不知道什么是对称加密的小伙伴请看这篇文章:https://blog.csdn.net/thy525/article/details/147700959
二、DES加密算法简介
DES(Data Encryption Standard)是一种经典的对称分组加密算法,由IBM于1970年代研发,1977年被美国国家标准局(NIST)正式采纳为联邦数据处理标准。其核心采用Feistel结构,通过16轮迭代完成加密/解密,密钥长度为56位(实际存储为64位,含8位奇偶校验位)。尽管已被AES取代,但DES仍广泛用于旧系统维护及密码学教学。
相关参数定义:
-
密钥(Key)
- 长度:64位(实际有效位56位,每字节第8位为奇偶校验位)
- 生成:需去除校验位后生成48位子密钥,每轮加密使用不同子密钥。
-
初始向量(IV)
- 仅CBC、CFB等模式需IV,ECB模式无需。
- 长度:64位(与分组大小一致),用于初始化加密链。
-
加密模式
- ECB(电子密码本):独立加密每个分组,相同明文生成相同密文,安全性弱。
- CBC(密码分组链接):前一分组密文与当前分组明文异或后加密,需IV。
- 其他模式:CFB、OFB等流密码模式较少使用。
-
填充方式
- PKCS7:补足N字节,每字节值为N(如缺3字节则补
0x03 0x03 0x03
)。 - ZeroPadding:用0填充,需额外标记实际数据长度。
- PKCS7:补足N字节,每字节值为N(如缺3字节则补
三、DES加密原理
-
初始置换(IP)
- 将64位明文按固定表置换,拆分为左右32位(L0、R0)。
-
轮函数(16轮)
- 扩展置换(E盒):将32位右半部分扩展为48位。
- 异或运算:与48位子密钥异或。
- S盒压缩:将48位分为8组6位,每组查S盒表压缩为4位,共32位。
- P盒置换:对32位结果置换,与左半部分异或,结果作为下一轮右半部分。
-
最终置换(IP⁻¹)
- 合并左右半部分,按逆置换表生成密文。
-
解密过程
- 与加密流程相同,但子密钥顺序相反。
四、快速识别DES加密的方法
4.1 密文长度判断
密文长度是 8 字节分组的整数倍经 Base64 编码后的结果,通常是 4 的倍数。
4.2 验证密文字符集
密文是 Base64 编码的字符串,由字符 A - Z
、a - z
、0 - 9
、+
、/
和 =
组成(用于填充)。
4.3 搜索常量数组
查找DES特有的S盒、P盒置换表(如S[0][0]=14
)。
4.4 代码特征识别
CryptoJS.DES.encrypt(text, key, { iv: iv });
总结:仅从密文本身较难一眼区分,但如果密文是 Base64 编码,且长度符合 8 字节分组加密后 Base64 编码的规律(如 12、16 等),结合较短的 64 位密钥和已知的 DES 加密库信息,可推测为 DES 加密结果。
五、代码实现
5.1 JavaScript实现DES加密解密
使用CryptoJS库实现DES加密解密,运算模式CBC,填充方式PKCS#7:
const CryptoJS = require('crypto-js');
// DES 加密函数,使用 CBC 模式和偏移量
function desEncrypt(plainText, keyHex, ivHex) {
const encrypted = CryptoJS.DES.encrypt(plainText, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
// DES 解密函数,使用 CBC 模式和偏移量
function desDecrypt(cipherText, keyHex, ivHex) {
const decrypted = CryptoJS.DES.decrypt(cipherText, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
const plainText = '123456'; // 明文
// 密钥与IV(需8字节)
const keyHex = CryptoJS.enc.Utf8.parse('12345678');
const ivHex = CryptoJS.enc.Utf8.parse('12345678');
// 加密
const encrypted = desEncrypt(plainText, keyHex, ivHex);
console.log('DES 加密后密文: ', encrypted);
console.log('DES 加密后密文长度: ', encrypted.length);
//解密
const decrypted = desDecrypt(encrypted, keyHex, ivHex);
console.log('DES 解密后: ', decrypted);
运行结果:
DES 加密后密文: HUX+7VtHgb0=
DES 加密后密文长度: 12
DES 解密后: 123456
5.2 Python实现DES加密解密
from Cryptodome.Cipher import DES
from Cryptodome.Util.Padding import pad, unpad
import base64
# DES 加密函数,使用 CBC 模式和偏移量
def desEncrypt(plainText, keyHex, ivHex):
cipher = DES.new(keyHex, DES.MODE_CBC, ivHex)
padded_plaintext = pad(plainText.encode('utf-8'), DES.block_size)
ciphertext = cipher.encrypt(padded_plaintext)
return base64.b64encode(ciphertext).decode('utf-8')
# DES 解密函数,使用 CBC 模式和偏移量
def desDecrypt(cipherText, keyHex, ivHex):
ciphertext = base64.b64decode(cipherText)
cipher = DES.new(keyHex, DES.MODE_CBC, ivHex)
decrypted_data = cipher.decrypt(ciphertext)
unpadded_data = unpad(decrypted_data, DES.block_size)
return unpadded_data.decode('utf-8')
plainText = '123456' # 明文
# 密钥与 IV(需 8 字节)
keyHex = b'12345678'
ivHex = b'12345678'
# 加密
encrypted = desEncrypt(plainText, keyHex, ivHex)
print('DES 加密后密文: ', encrypted)
print('DES 加密后密文长度: ', len(encrypted))
# 解密
decrypted = desDecrypt(encrypted, keyHex, ivHex)
print('DES 解密后: ', decrypted)
运行结果:
DES 加密后密文: HUX+7VtHgb0=
DES 加密后密文长度: 12
DES 解密后: 123456