📚 对称加密算法解析:DES、AES及其在pycryptodome
和 crypto-js
模块中的应用
🗝️ DES 算法
算法原理
数据加密标准(DES)是一种对称密钥加密算法,用于保护数据的安全。DES 使用一个 56 位的密钥进行加密和解密,将数据块分为 64 位的块进行处理。DES 是一种 Feistel 网络,每个数据块经过 16 轮的处理,其中包括置换和替换操作,以实现加密。
主要原理:
- 密钥调度:将 64 位的密钥压缩成 56 位,并通过循环左移生成 16 个子密钥。
- 初始置换(IP):对输入数据块进行初始置换。
- 轮函数:每一轮包含扩展置换、S-盒替换、P-盒置换和异或操作。
- 逆初始置换(IP-1):在所有轮处理完后,对数据进行逆初始置换得到最终的密文。
Python 实现
使用 pycryptodome
库来实现 DES 加密和解密:
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
def des_encrypt_decrypt(data, key, mode):
cipher = DES.new(key, DES.MODE_ECB)
if mode == 'encrypt':
# 填充数据至 DES 块大小
padded_data = pad(data.encode('utf-8'), DES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data
elif mode == 'decrypt':
decrypted_data = cipher.decrypt(data)
unpadded_data = unpad(decrypted_data, DES.block_size)
return unpadded_data.decode('utf-8')
else:
raise ValueError("Invalid mode. Choose 'encrypt' or 'decrypt'.")
# 示例
key = b'8bytekey' # 8 字节的密钥
data = "Hello, DES!"
encrypted = des_encrypt_decrypt(data, key, 'encrypt')
decrypted = des_encrypt_decrypt(encrypted, key, 'decrypt')
print("Encrypted:", encrypted)
print("Decrypted:", decrypted)
输入输出示例:
- 输入:
"Hello, DES!"
, 密钥:b'8bytekey'
- 输出:
- 加密结果:
b'\x9d\xc2\xa5\x16\x19\x1c\xf3\x8f'
- 解密结果:
"Hello, DES!"
- 加密结果:
JavaScript 实现(使用 crypto-js
模块)
const CryptoJS = require('crypto-js');
function desEncryptDecrypt(data, key, mode) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
if (mode === 'encrypt') {
const encrypted = CryptoJS.DES.encrypt(data, keyHex, { mode: CryptoJS.mode.ECB });
return encrypted.toString();
} else if (mode === 'decrypt') {
const decrypted = CryptoJS.DES.decrypt(data, keyHex, { mode: CryptoJS.mode.ECB });
return decrypted.toString(CryptoJS.enc.Utf8);
} else {
throw new Error("Invalid mode. Choose 'encrypt' or 'decrypt'.");
}
}
// 示例
const key = '8bytekey'; // 8 字节的密钥
const data = 'Hello, DES!';
const encrypted = desEncryptDecrypt(data, key, 'encrypt');
const decrypted = desEncryptDecrypt(encrypted, key, 'decrypt');
console.log("Encrypted:", encrypted);
console.log("Decrypted:", decrypted);
输入输出示例:
- 输入:
"Hello, DES!"
, 密钥:"8bytekey"
- 输出:
- 加密结果:
"3B3d4a...bcd5"
(加密的密文) - 解密结果:
"Hello, DES!"
- 加密结果:
🔐 AES 算法
算法原理
高级加密标准(AES)是对称密钥加密标准,用于替代 DES。AES 支持 128 位、192 位和 256 位密钥长度,并处理 128 位的块。AES 采用 10、12 或 14 轮的处理,取决于密钥的长度。
主要原理:
- 密钥扩展:从原始密钥生成多个轮密钥。
- 轮函数:每轮包含字节替换(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)操作。
- 最终轮:不包括列混淆操作。
Python 实现
使用 pycryptodome
库来实现 AES 加密和解密:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
def aes_encrypt_decrypt(data, key, mode):
cipher = AES.new(key, AES.MODE_ECB)
if mode == 'encrypt':
# 填充数据至 AES 块大小
padded_data = pad(data.encode('utf-8'), AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data
elif mode == 'decrypt':
decrypted_data = cipher.decrypt(data)
unpadded_data = unpad(decrypted_data, AES.block_size)
return unpadded_data.decode('utf-8')
else:
raise ValueError("Invalid mode. Choose 'encrypt' or 'decrypt'.")
# 示例
key = os.urandom(16) # 16 字节的密钥
data = "Hello, AES!"
encrypted = aes_encrypt_decrypt(data, key, 'encrypt')
decrypted = aes_encrypt_decrypt(encrypted, key, 'decrypt')
print("Encrypted:", encrypted)
print("Decrypted:", decrypted)
输入输出示例:
- 输入:
"Hello, AES!"
, 密钥:b'...key...'
(随机生成) - 输出:
- 加密结果:
b'\x1f\x23\xfe...78'
- 解密结果:
"Hello, AES!"
- 加密结果:
JavaScript 实现(使用 crypto-js
模块)
const CryptoJS = require('crypto-js');
function aesEncryptDecrypt(data, key, mode) {
const keyHex = CryptoJS.enc.Hex.parse(key);
if (mode === 'encrypt') {
const encrypted = CryptoJS.AES.encrypt(data, keyHex, { mode: CryptoJS.mode.ECB });
return encrypted.toString();
} else if (mode === 'decrypt') {
const decrypted = CryptoJS.AES.decrypt(data, keyHex, { mode: CryptoJS.mode.ECB });
return decrypted.toString(CryptoJS.enc.Utf8);
} else {
throw new Error("Invalid mode. Choose 'encrypt' or 'decrypt'.");
}
}
// 示例
const key = CryptoJS.enc.Hex.parse('00112233445566778899aabbccddeeff'); // 16 字节密钥
const data = 'Hello, AES!';
const encrypted = aesEncryptDecrypt(data, key, 'encrypt');
const decrypted = aesEncryptDecrypt(encrypted, key, 'decrypt');
console.log("Encrypted:", encrypted);
console.log("Decrypted:", decrypted);
输入输出示例:
- 输入:
"Hello, AES!"
, 密钥:"00112233445566778899aabbccddeeff"
- 输出:
- 加密结果:
"U2FsdGVkX1+...7w=="
(加密的密文) - 解密结果:
"Hello, AES!"
- 加密结果:
🛠️ 拓展用法
1. 加盐(仅适用于 DES 和 AES)
Python 实现:
from Crypto.Random import get_random_bytes
def aes_encrypt_with_salt(data, key, salt):
key_with_salt = key + salt
cipher = AES.new(key_with_salt[:16], AES.MODE_ECB)
padded_data = pad(data.encode('utf-8'), AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data
# 示例
key = get_random_bytes(16)
salt = get_random_bytes(8)
data = "Hello, AES with Salt!"
encrypted = aes_encrypt_with_salt(data, key, salt)
print("Encrypted with Salt:", encrypted)
输入输出示例:
- 输入:
"Hello, AES with Salt!"
, 密钥:b'...'
(随机生成), 盐值:b'...'
(随机生成) - 输出:
- 加密结果:
b'\x12\x34\x56\x78...ef'
(加密的密文)
- 加密结果:
2. 哈希化密钥(密钥衍生)
Python 实现:
from Crypto.Protocol.KDF import scrypt
def derive_key(password, salt):
return scrypt(password.encode('utf-8'), salt, 16, N=2**14, r=8, p=1)
# 示例
password = "mysecretpassword"
salt = get_random_bytes(16)
derived_key = derive_key(password, salt)
print("Derived Key:", derived_key)
**输入
输出示例**:
- 输入: 密码:
"mysecretpassword"
, 盐值:b'...'
(随机生成) - 输出:
- 派生密钥:
b'...'
(派生的密钥)
- 派生密钥:
3. 修改加密算法参数(如填充方式)
Python 实现:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
def aes_encrypt_with_custom_padding(data, key, padding_length):
cipher = AES.new(key, AES.MODE_ECB)
padded_data = data.encode('utf-8') + bytes([padding_length] * padding_length)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data
# 示例
key = get_random_bytes(16)
data = "Hello, Custom Padding!"
encrypted = aes_encrypt_with_custom_padding(data, key, 16)
print("Encrypted with Custom Padding:", encrypted)
输入输出示例:
- 输入:
"Hello, Custom Padding!"
, 密钥:b'...'
(随机生成), 填充长度:16
- 输出:
- 加密结果:
b'...'
(加密的密文)
- 加密结果:
4. 密钥扩展(从较短密钥生成较长密钥)
Python 实现:
from Crypto.Hash import SHA256
def extend_key(short_key):
return SHA256.new(short_key).digest()
# 示例
short_key = b'shortkey'
extended_key = extend_key(short_key)
print("Extended Key:", extended_key)
输入输出示例:
- 输入: 短密钥:
b'shortkey'
- 输出:
- 扩展密钥:
b'...'
(扩展后的密钥)
- 扩展密钥:
5. 加密的哈希化(加密后哈希化)
Python 实现:
from Crypto.Hash import SHA256
def hash_after_encryption(encrypted_data):
hash_object = SHA256.new(data=encrypted_data)
return hash_object.hexdigest()
# 示例
data = "Hello, Hash after Encryption!"
encrypted = aes_encrypt_decrypt(data, key, 'encrypt')
hashed = hash_after_encryption(encrypted)
print("Hashed Encrypted Data:", hashed)
输入输出示例:
- 输入:
"Hello, Hash after Encryption!"
, 加密数据:b'...'
- 输出:
- 哈希值:
"d2d2d2d2d2...d2d2"
- 哈希值:
以上示例展示了 DES 和 AES 对称加密算法的基本使用方法,以及如何在 Python 和 JavaScript 中实现这些算法。此外,还涵盖了一些拓展用法,例如加盐、密钥衍生、修改加密算法参数等。这些方法为实际应用中的加密需求提供了丰富的解决方案。