密码学的目标
1. 机密性(Confidentiality)
目标:保护信息不被未授权访问。
- 通过 加密(Encryption)技术确保数据只能被授权方解密和读取。
- 主要方法:
- 对称加密(AES、3DES):用于保护数据存储或高速传输。
- 非对称加密(RSA、ECC):用于安全通信和身份验证(如SSL/TLS)。
- 数据脱敏(Masking)、零知识证明(Zero-Knowledge Proofs)等技术。
2. 完整性(Integrity)
目标:确保数据未被篡改或损坏。
- 使用 哈希算法(Hashing) 生成唯一的摘要值,以检测数据篡改。
- 主要方法:
- 哈希函数(MD5、SHA-256):确保数据完整性。
- 消息认证码(MAC):如 HMAC-SHA256,验证数据完整性和真实性。
- 数字签名:结合哈希算法和公钥加密,确保数据和发送者的身份可信。
3. 可用性(Availability)
目标:确保加密数据在授权情况下仍然可以正常使用。
- 加密算法不能影响系统性能,数据在需要时必须可用。
- 主要方法:
- 密钥管理(Key Management):确保密钥安全存储和分发,避免因密钥丢失导致数据无法解密。
- 冗余和容错(Redundancy & Fault Tolerance):确保加密系统不会因单点故障而失效(如RAID、数据备份)。
- 抗拒绝服务攻击(防止 DoS/DDoS 对加密系统的影响)。
4. 真实性(Authentication)
目标:确保通信双方身份真实,防止伪造身份的攻击。
- 主要方法:
- 数字签名(Digital Signatures):使用公钥加密验证数据来源。
- PKI(公钥基础设施):通过数字证书(如 X.509 证书)验证用户身份。
- 多因素身份验证(MFA):结合密码学技术(如 OTP、FIDO2、证书认证)。
5. 抗抵赖性(Non-repudiation)
目标:防止发送者或接收者否认他们的行为。
- 主要方法:
- 数字签名:提供可靠的身份认证,防止发送者事后否认已发送的数据。
- 时间戳(Timestamping):记录交易时间,确保数据的法律效力。
- 区块链技术:去中心化的交易记录,提高数据可信度。
柯克霍夫原则(Kerckhoffs’s Principle)
柯克霍夫原则(Kerckhoffs’s Principle) 是密码学中的一个核心原则,由荷兰密码学家奥古斯特·柯克霍夫(Auguste Kerckhoffs) 在 1883 年提出。该原则的核心思想是:
“密码系统的安全性不应依赖于算法的保密性,而应仅依赖于密钥的保密性。”
柯克霍夫原则的关键要点包括:
- 加密算法可以公开:攻击者可以知道算法的具体实现,但仍无法破解消息。
- 密钥必须保密:系统的安全性应该完全依赖于密钥的机密性,而不是算法的隐秘性。
- 即使敌人掌握了整个系统(除了密钥),也无法轻易破解:换句话说,即使攻击者知道加密方法,只要密钥足够安全,攻击者仍无法解密数据。
- 系统应当是可用的:即使密钥丢失,系统仍应支持快速更换密钥,而不是整个系统报废。
Nonce(Number Once,随机数/一次性数值)
Nonce 是密码学和计算机安全领域中的一个一次性使用的随机数或计数器值,通常用于防止重放攻击、确保数据唯一性或增强加密安全性。
1. Nonce 的主要作用
Nonce 在加密系统中主要用于以下几个方面:
防止重放攻击(Replay Attack)
- 在身份验证或数据传输过程中,如果没有 Nonce,攻击者可以截取数据包并重复发送,导致安全漏洞。
- 解决方案:使用 随机 Nonce 或 递增计数器 Nonce,确保每条消息都是唯一的,防止重复攻击。
用于密码学协议
- TLS/SSL 握手:客户端和服务器在建立安全连接时,交换 Nonce 以防止旧密钥被重复使用。
- 区块链(如比特币):矿工需要找到一个合适的 Nonce,使得区块哈希满足特定条件(如比特币的 PoW 机制)。
- 加密算法(如 AES-GCM, ChaCha20-Poly1305):加密时,Nonce 确保每次加密生成不同的密文,即使明文相同。
确保随机性和唯一性
- 在加密过程中,Nonce 可以作为初始化向量(IV),确保相同的明文不会生成相同的密文,提高安全性。
- 在身份验证协议(如 Kerberos)中,Nonce 确保身份验证请求是唯一的,防止攻击者重复使用旧请求。
2. Nonce 的类型
Nonce 主要有两种类型:
类型 | 特点 | 应用场景 |
---|---|---|
随机 Nonce | 由加密安全的随机数生成器(CSPRNG)生成 | TLS、区块链、身份验证 |
计数器 Nonce | 递增的数值,确保唯一性 | AES-GCM、数据库事务 |
不同应用场景需要不同的 Nonce 生成方式。例如,在 TLS 协议中,使用的是 随机 Nonce,而 AES-GCM 加密模式通常使用 计数器 Nonce。
3. Nonce 示例
TLS/SSL 中的 Nonce
在 TLS 1.2 和 TLS 1.3 握手过程中,服务器和客户端会交换随机数(Nonce)以避免重放攻击:
Client Hello:
Nonce: 0xA1B2C3D4E5F6...
Server Hello:
Nonce: 0xF6E5D4C3B2A1...
这样,即使攻击者截获了 TLS 握手信息,无法重用相同的 Nonce 进行攻击。
零知识证明(Zero-Knowledge Proof, ZKP
零知识证明(ZKP, Zero-Knowledge Proof) 是一种密码学协议,允许证明者(Prover) 在不泄露任何秘密信息的情况下,向 验证者(Verifier) 证明自己知道某个秘密。
1. 零知识证明的特点
一个好的零知识证明协议需要满足 3 个关键特性:
- 完备性(Completeness)
- 如果证明者真的知道秘密,验证者就一定会验证通过。
- 可靠性(Soundness)
- 如果证明者不知道秘密,几乎不可能骗过验证者。
- 零知识性(Zero-Knowledge)
- 证明过程中,验证者无法获得任何关于秘密的信息,只知道证明者确实拥有这个秘密。
2. 经典的零知识证明示例
山洞问题(The Ali Baba Cave)
故事背景:
- 山洞有两个入口(A 和 B),里面有一个魔法门,只有知道魔法咒语的人才能打开。
- 佩姬(Peggy) 想向 维克多(Victor) 证明自己知道咒语,但又不想告诉维克多。
证明过程:
- 维克多站在洞外,要求佩姬随机从 A 或 B 进入山洞。
- 佩姬随便选一个入口(比如 A 进入)。
- 维克多在外面随机要求她从 A 或 B 出来。
- 如果佩姬真的知道魔法咒语,她就可以随意从任何出口出来。
- 这个过程重复多次,如果佩姬每次都成功,维克多就相信她知道咒语。
关键点:
- 维克多不会学到咒语(零知识性)。
- 如果佩姬不会咒语,她有 50% 的概率猜对出口,但多次测试后,骗过维克多的概率会接近 0(可靠性)。
3. 真实应用中的零知识证明
区块链 & 加密货币
- ZK-SNARKs & ZK-STARKs(零知识简洁非交互式知识论证):
- Zcash 使用 ZK-SNARKs 进行匿名交易,证明交易有效但不泄露金额和发送方信息。
- Ethereum 也在使用 ZK-Rollups 扩展网络,减少计算量,提高隐私性。
身份验证(无需密码)
- 零知识身份验证:证明用户拥有密码或身份信息,而不泄露具体内容。例如:
- 证明你是某个银行的客户,而不透露你的账户号码。
- 证明你超过 18 岁,而不透露你的出生日期。
电子投票
- 确保投票者的身份被验证,但不暴露他们投给了谁。
4. ZKP 的两种主要类型
类型 | 特点 | 代表应用 |
---|---|---|
交互式零知识证明(Interactive ZKP) | 证明者和验证者多次交互 | 经典的山洞问题 |
非交互式零知识证明(Non-Interactive ZKP, NIZK) | 只需提供一个证明文件,无需多次交互 | ZK-SNARKs、ZK-STARKs |
- ZK-SNARKs(简洁非交互式零知识证明):计算快,但需要可信初始化。
- ZK-STARKs(透明可扩展零知识证明):计算更复杂,但无需可信初始化,安全性更高。
5. 零知识证明的未来
- Web3 & 隐私保护:用于去中心化身份认证(DID)、DAO 投票、NFT 交易保护。
- 隐私支付:未来的银行可能会使用零知识证明处理交易,既能满足合规性,又能保护用户隐私。
- 人工智能 & 机器学习:零知识证明可以用于 AI 模型推理,确保数据安全。
Vernam密码(Vernam Cipher)
Vernam 密码是一种 一次性密码本(One-Time Pad, OTP) 加密方法,由 Gilbert Vernam 在 1917 年发明,被认为是唯一绝对安全的加密算法,但同时难以实际应用。
密码
1. 运动密钥密码(Dynamic Key Cipher)
运动密钥密码指的是加密过程中,密钥会不断变化,而不是使用固定密钥。例如:
- 一次性密码本(One-Time Pad, OTP):每个明文字符使用不同的密钥进行加密。
- 会话密钥(Session Key):TLS 等协议中,每次通信都会生成新的加密密钥。
- 动态密钥扩展(Dynamic Key Expansion):密钥根据某种算法动态变化,如 RSA+AES 组合加密。
优势:
增强安全性,避免长期密钥被攻击。
适用于安全通信协议,如 TLS、IPsec、SSH 等。
2. 块密码(Block Cipher)
块密码是一种对 固定大小的明文块 进行加密的算法,如 AES、DES。它通常将明文分成 多个固定长度的块(如 128 位),然后使用相同的密钥分别加密这些块。
常见的块密码算法:
- AES(高级加密标准):常见于 TLS、VPN、Wi-Fi WPA2 等。
- DES(数据加密标准)(已淘汰)。
- 3DES(三重 DES)(较老,已逐渐被 AES 取代)。
块密码的模式(Block Cipher Modes):
模式 | 特点 |
---|---|
ECB(电子密码本模式) | 不安全,相同明文加密结果相同,容易被分析。 |
CBC(密码块链接模式) | 每个块与上一个密文块 XOR,安全性更高。 |
CFB(密码反馈模式) | 适合流式数据加密。 |
OFB(输出反馈模式) | 适合流式数据加密,避免误差扩散。 |
GCM(Galois/Counter 模式) | 现代模式,支持认证加密(AEAD)。 |
示例(AES-CBC 模式):
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(16) # 生成 16 字节密钥
iv = get_random_bytes(16) # 生成 16 字节 IV
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = b"Hello, World! " # 明文需要填充到 16 字节
ciphertext = cipher.encrypt(plaintext)
print("密文:", ciphertext.hex())
3. 流密码(Stream Cipher)
流密码是一种按 字节或比特 进行加密的算法,适用于 实时数据流(VoIP、视频通话)。它的加密密钥会不断变化,生成一个密钥流(Keystream),然后用 XOR 操作加密明文。
常见流密码算法:
- RC4(已被淘汰):曾用于 Wi-Fi WEP,现在不安全。
- ChaCha20:目前最安全的流密码之一,广泛用于 TLS 1.3、WireGuard VPN。
- Salsa20:ChaCha20 的前身,安全性较高。
流密码 vs 块密码:
对比项 | 块密码 | 流密码 |
---|---|---|
加密单位 | 固定大小的块(如 128 位) | 按位或按字节流式加密 |
速度 | 相对较慢 | 快,适用于实时通信 |
适用场景 | 硬盘加密、数据库加密 | VoIP、视频流加密 |
示例(ChaCha20 加密):
from Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes
key = get_random_bytes(32) # ChaCha20 需要 256-bit 密钥
nonce = get_random_bytes(8) # ChaCha20 需要 8 字节 nonce
cipher = ChaCha20.new(key=key, nonce=nonce)
plaintext = b"Hello, Stream Cipher!"
ciphertext = cipher.encrypt(plaintext)
print("密文:", ciphertext.hex())
4. 混淆(Confusion)与扩散(Diffusion)
这两个概念由 Claude Shannon(香农) 提出,是现代密码学的两个核心设计原则。
混淆(Confusion)
- 让密文和密钥之间的关系尽可能复杂,使攻击者难以推测密钥。
- 方法:使用 S 盒(Substitution box) 进行替换,使密钥和密文之间的关系复杂化。
- 示例:AES 使用 S 盒(S-Box),改变字节值,使其不可预测。
扩散(Diffusion)
- 让明文的每一位都影响密文的多个位,防止攻击者找到明文和密文的直接关系。
- 方法:使用 置换(Permutation),如 AES 的 ShiftRows 和 MixColumns 变换。
- 示例:如果改变明文的 1 位,整个密文都会大幅变化(雪崩效应)。
AES 的混淆与扩散
AES 操作 | 作用 |
---|---|
SubBytes(S 盒) | 通过替换增加混淆 |
ShiftRows | 通过行移位增加扩散 |
MixColumns | 通过列混合增加扩散 |
非对称密钥算法(Asymmetric Encryption)
非对称加密(Asymmetric Encryption)是一种 公钥密码学(Public-Key Cryptography),使用两个不同的密钥:
- 公钥(Public Key):用于加密,可公开。
- 私钥(Private Key):用于解密,必须保密。
特点:
提高安全性:即使公钥泄露,也无法解密数据。
适用于身份验证、数字签名、密钥交换等。
计算速度较慢:相比对称加密(AES),非对称加密计算量大,通常用于加密小数据(如密钥交换)。
1. 经典非对称加密算法
算法 | 密钥长度 | 安全性 | 应用场景 |
---|---|---|---|
RSA | 2048+ 位 | 依赖大整数分解 | SSL/TLS、数字签名 |
ECC(椭圆曲线加密) | 256+ 位 | 比 RSA 更高效 | 区块链、数字签名 |
DSA(数字签名算法) | 1024+ 位 | 主要用于签名 | 数字签名 |
Diffie-Hellman(DH) | 2048+ 位 | 用于密钥交换 | TLS、VPN |
2. RSA 加密
RSA(Rivest-Shamir-Adleman) 是最经典的非对称加密算法,基于大整数分解难题。
RSA 工作原理
-
密钥生成:
- 选取两个大素数
p
和q
。 - 计算
n = p × q
作为 模数(modulus)。 - 计算欧拉函数:
φ(n) = (p-1) × (q-1)
。 - 选择公钥指数
e
(通常为 65537)。 - 计算私钥
d
,使d × e ≡ 1 (mod φ(n))
。
- 选取两个大素数
-
加密:
C = M e m o d n C = M^e \mod n C=MemodnM
是明文,C
是密文。
-
解密:
M = C d m o d n M = C^d \mod n M=Cdmodnd
只能由私钥计算。
Python 示例(RSA 加密 & 解密):
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
# 生成 RSA 密钥对
key = RSA.generate(2048)
public_key = key.publickey()
# 加密
cipher_rsa = PKCS1_OAEP.new(public_key)
plaintext = b"Hello, RSA!"
ciphertext = cipher_rsa.encrypt(plaintext)
print("密文:", ciphertext.hex())
# 解密
cipher_rsa = PKCS1_OAEP.new(key)
decrypted = cipher_rsa.decrypt(ciphertext)
print("解密后明文:", decrypted.decode())
3. ECC(椭圆曲线加密)
ECC(Elliptic Curve Cryptography)是一种基于椭圆曲线离散对数问题的非对称加密算法,比 RSA 更安全、密钥更短、计算更快。
ECC vs RSA
算法 | 安全等效(RSA vs ECC) | 密钥长度 |
---|---|---|
RSA | 2048 位 | 2048 位 |
ECC | 2048 位 RSA ≈ 256 位 ECC | 256 位 |
ECC 应用:
- 区块链(Bitcoin, Ethereum)
- SSL/TLS
- 移动设备(低功耗场景)
Python 示例(ECC 密钥生成):
from ecdsa import SigningKey, SECP256k1
# 生成 ECC 密钥对
private_key = SigningKey.generate(curve=SECP256k1)
public_key = private_key.verifying_key
print("私钥:", private_key.to_string().hex())
print("公钥:", public_key.to_string().hex())
4. Diffie-Hellman(DH)密钥交换
Diffie-Hellman 不是用于加密,而是用于安全地交换对称密钥。
工作原理
- Alice 和 Bob 选择一个公开的素数
p
和基数g
。 - Alice 选择私钥
a
,Bob 选择私钥b
。 - Alice 计算
A = g^a mod p
并发送给 Bob。 - Bob 计算
B = g^b mod p
并发送给 Alice。 - Alice 计算共享密钥
K = B^a mod p
。 - Bob 计算共享密钥
K = A^b mod p
。 - 最终双方计算出的
K
是相同的,可用于对称加密(如 AES)。
Python 示例(DH 密钥交换):
from cryptography.hazmat.primitives.asymmetric import dh
# 生成 DH 参数
parameters = dh.generate_parameters(generator=2, key_size=2048)
# 生成 Alice 和 Bob 的私钥
alice_private_key = parameters.generate_private_key()
bob_private_key = parameters.generate_private_key()
# 计算公钥
alice_public_key = alice_private_key.public_key()
bob_public_key = bob_private_key.public_key()
# 交换公钥并计算共享密钥
alice_shared_key = alice_private_key.exchange(bob_public_key)
bob_shared_key = bob_private_key.exchange(alice_public_key)
# 确保双方计算出的密钥相同
assert alice_shared_key == bob_shared_key
print("共享密钥:", alice_shared_key.hex())
5. 数字签名
非对称加密不仅用于加密,还可用于数字签名,用于身份验证和完整性验证。
数字签名过程(以 RSA 为例)
-
签名:
- 计算消息
M
的哈希值H(M)
。 - 用私钥
d
对H(M)
进行签名:S = H(M)^d mod n
。 - 发送
(M, S)
给接收方。
- 计算消息
-
验证:
- 用公钥
e
计算H(M) = S^e mod n
。 - 如果计算结果与接收到的
M
经过哈希计算的值相同,则签名有效。
- 用公钥
Python 示例(RSA 签名 & 验证):
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
# 生成 RSA 密钥
key = RSA.generate(2048)
public_key = key.publickey()
# 签名
message = b"Hello, Digital Signature!"
hash_msg = SHA256.new(message)
signature = pkcs1_15.new(key).sign(hash_msg)
# 验证
try:
pkcs1_15.new(public_key).verify(hash_msg, signature)
print("签名验证成功!")
except:
print("签名验证失败!")
对称密码的运行模式(Block Cipher Modes of Operation)
在 对称加密(Symmetric Encryption) 中,块密码(Block Cipher)如 AES(高级加密标准) 需要特定的**运行模式(Modes of Operation)**来加密数据块。这些模式决定了如何处理多个块的数据。
1. 电子密码本模式(ECB - Electronic Codebook)
特点
- 每个数据块(128 位)单独加密,相同的明文块加密后总是相同的密文块。
- 容易受到模式分析攻击(相同的输入总是产生相同的输出)。
- 不推荐使用!
适用场景
不建议用于任何安全应用!
2. 密码块链接模式(CBC - Cipher Block Chaining)
特点
- 每个密文块都会影响下一个块,避免模式泄露。
- 需要一个随机初始化向量(IV),保证相同明文每次加密结果不同。
- 如果某个块损坏,后续解密可能会受到影响。
加密过程
C i = E k ( P i ⊕ C i − 1 ) C_i = E_k(P_i \oplus C_{i-1}) Ci=Ek(Pi⊕Ci−1)
C_i
:第i
块密文P_i
:第i
块明文C_{i-1}
:前一块的密文IV
:第一块需要的初始化向量
示例(AES-CBC 加密 & 解密)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
key = get_random_bytes(16) # 16字节AES密钥
iv = get_random_bytes(16) # 16字节随机IV
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = b"Hello, CBC Mode!" # 明文
padded_text = pad(plaintext, AES.block_size) # 填充明文
ciphertext = cipher.encrypt(padded_text) # 加密
print("密文:", ciphertext.hex())
# 解密
decipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(decipher.decrypt(ciphertext), AES.block_size)
print("解密后:", decrypted.decode())
适用场景
文件加密、数据库加密、磁盘加密(BitLocker、SSL/TLS)。
3. 计算反馈模式(CFB - Cipher Feedback)
特点
- 像流密码一样工作(不需要填充)。
- 加密时一个字节(或更小单位)输出一个字节。
- 适用于实时数据流(如 VoIP、视频流)。
加密过程
C i = P i ⊕ E k ( C i − 1 ) C_i = P_i \oplus E_k(C_{i-1}) Ci=Pi⊕Ek(Ci−1)
P_i
是明文,C_i
是密文。
适用场景
流式数据加密(如网络通信、VoIP)。
4. 输出反馈模式(OFB - Output Feedback)
特点
- 与 CFB 类似,但不使用前一个密文,而是不断加密 IV 生成密钥流。
- 错误不会扩散(如果某个密文块损坏,不影响其他块)。
- 适用于流式加密,避免误差传播。
加密过程
O
i
=
E
k
(
O
i
−
1
)
O_i = E_k(O_{i-1})
Oi=Ek(Oi−1)
C
i
=
P
i
⊕
O
i
C_i = P_i \oplus O_i
Ci=Pi⊕Oi
O_i
是加密 IV 的输出。
适用场景
无线通信、卫星通信。
5. 计数器模式(CTR - Counter)
特点
- 每个块的加密密钥由一个递增的计数器(Nonce + Counter)生成。
- 加密和解密可以并行执行(相比 CBC 更快)。
- 像流密码一样,无需填充。
加密过程
C i = P i ⊕ E k ( Nonce ∣ ∣ i ) C_i = P_i \oplus E_k(\text{Nonce} || i) Ci=Pi⊕Ek(Nonce∣∣i)
Nonce
是随机数,i
是计数器。
示例(AES-CTR 加密 & 解密)
from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto.Random import get_random_bytes
key = get_random_bytes(16)
nonce = get_random_bytes(8) # 8字节Nonce
ctr = Counter.new(64, prefix=nonce)
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
plaintext = b"Hello, CTR Mode!"
ciphertext = cipher.encrypt(plaintext)
print("密文:", ciphertext.hex())
# 解密
ctr = Counter.new(64, prefix=nonce)
decipher = AES.new(key, AES.MODE_CTR, counter=ctr)
decrypted = decipher.decrypt(ciphertext)
print("解密后:", decrypted.decode())
适用场景
多核并行加密(TLS 1.2、IPsec VPN)
云存储、区块链(比特币的 AES 加密)
6. Galois/Counter Mode(GCM - Galois/Counter Mode)
特点
- 基于 CTR,但增加了认证(AEAD)。
- 提供完整性保护,防止篡改(适用于 HTTPS、TLS 1.3)。
- 比 CBC 更快,支持并行计算。
适用场景
HTTPS(TLS 1.3)、IPsec、SSH。
7. 各模式对比
模式 | 特点 | 安全性 | 适用场景 |
---|---|---|---|
ECB | 每个块独立加密 | 不安全 | 不推荐 |
CBC | 依赖 IV,每块加密依赖前一块 | 安全 | 文件加密、数据库 |
CFB | 类似流密码,适用于实时加密 | 安全 | VoIP、流数据 |
OFB | 适用于流式加密 | 安全 | 无线通信 |
CTR | 可并行,计算快 | 安全 | 多核并行加密 |
GCM | 认证加密(AEAD),防篡改 | 高安全 | TLS 1.3, HTTPS |
国际数据加密算法(IDEA - International Data Encryption Algorithm)
IDEA 是一种对称密钥加密算法,它于 1990 年由 Xuejia Lai 和 James Massey 提出,成为 国际数据加密算法(IDEA),并在多种安全协议中得到应用。
IDEA 算法的基本概念
- 对称加密:使用相同的密钥进行加密和解密。
- 块加密算法:将数据分成固定大小的块进行加密(IDEA 每次处理 64 位的明文)。
- 密钥长度:128 位的密钥。
IDEA 的工作原理
IDEA 采用一种 基于替换与置换的结构,它对每个 64 位的输入数据进行 8 轮(round)加密,经过替换、移位等操作,最终输出密文。
1. 数据分块与密钥生成
- 64 位的输入块:数据块被分成 4 个 16 位的小块。
- 128 位密钥:128 位密钥被分成 8 个 16 位的子密钥。
2. 每一轮的操作
IDEA 采用 密钥扩展,从 128 位的密钥中派生出 52 个子密钥(每轮使用 6 个密钥)。每一轮通过如下步骤处理:
- 替代(Substitution):使用非线性代换,替换明文块中的各个部分。
- 置换(Permutation):对数据进行移位和置换,增加混淆性。
- 与密钥操作(Key Mixing):将密钥与数据块进行混合。
- 异或(XOR):将数据块与其他结果异或,提高安全性。
Blowfish 加密算法
Blowfish 是一个 对称密钥加密算法,由 Bruce Schneier 在 1993 年设计。Blowfish 设计的主要目标是提供一个快速、安全且灵活的加密算法,可以替代当时被认为不安全的 DES(数据加密标准)。它是一个 块加密算法,每次加密 64 位的数据块。
Blowfish 算法的特性
- 对称密钥:使用相同的密钥进行加密和解密。
- 64 位数据块:每次加密 64 位的数据块。
- 密钥长度可变:Blowfish 允许使用 32 位至 448 位(即 4 到 56 字节)长度的密钥,具有极大的灵活性。
- 迭代轮次:Blowfish 的加密操作共执行 16 轮(rounds)。
- 替换和置换:Blowfish 采用了 Feistel 网络 结构,结合替换与置换操作进行加密。
Blowfish 加密过程
Blowfish 使用 Feistel 网络(类似于 DES)来加密数据。整个过程包含如下几个重要部分:
-
密钥扩展:
- 密钥被扩展成多个子密钥(包括 P-array 和 S-boxes),用于加密每个数据块。
- 密钥的长度从 32 位到 448 位不等,支持灵活的密钥长度。
-
数据块加密:
- 明文数据被分成 64 位的数据块,每个数据块都经过 16 轮的加密过程。
- 每轮使用相应的子密钥进行操作,主要包括 异或(XOR)、替代(Substitution)和 移位(Shift)等操作。
-
Feistel 结构:
- 每一轮操作都是基于 Feistel 网络结构,其中的核心部分是通过 S-box 进行的代换和混淆操作。
- 加密过程使用一个 前向和反向 结构,确保数据的混淆和扩散。
Blowfish 加密算法的工作原理
-
初始化:
- 使用密钥生成 P-array(包含 18 个 32 位元素)和 S-boxes(包含 4 个 256 元素的数组),这些值用于在加密和解密过程中不断混淆数据。
-
Feistel 网络:
- 将 64 位明文分为两个 32 位部分。
- 使用多个 S-box 和 P-array,反复替代、加法和异或操作,产生最终的密文。
-
16 轮加密:
- 每一轮使用 P-array 中的不同子密钥,进行 Feistel 网络的迭代操作。最终,密文产生。
Feistel 网络的一轮加密过程:
L i = R i − 1 , R i = L i − 1 ⊕ F ( R i − 1 , P i ) L_i = R_{i-1},\quad R_i = L_{i-1} \oplus F(R_{i-1}, P_i) Li=Ri−1,Ri=Li−1⊕F(Ri−1,Pi)
- L 和 R:每轮的左侧和右侧数据
- F:使用当前的 S-box 和子密钥生成的函数
Blowfish 的安全性
Blowfish 设计时考虑了抗密码分析(例如差分分析和线性分析)的能力,使用了复杂的子密钥生成机制和多轮的迭代过程,使得它对大多数常见攻击具有较强的抵抗力。虽然在其设计时非常安全,但 Blowfish 目前已被认为在 现代加密标准 中略显过时,主要是因为:
- 64 位数据块:相比于 AES 等算法的 128 位数据块,Blowfish 的 64 位数据块容易受到 生日攻击(Birthday Attack)等一些特定攻击的威胁。
- 较小的密钥空间:Blowfish 支持的最大密钥长度为 448 位,相对较小的密钥空间在某些情况下可能会被突破。
因此,Blowfish 通常作为 过渡加密算法,不推荐用于高安全性要求的场景。
Blowfish 的应用
- VPN 和网络安全:Blowfish 曾被广泛应用于一些 VPN 协议(如 OpenVPN)和 加密通信,但随着更强的 AES 和 ChaCha20 的出现,Blowfish 使用频率逐渐减少。
- 文件加密:一些旧版的加密工具和软件(如 PGP)也使用过 Blowfish。
- 旧版加密协议:一些旧的加密协议和工具(例如 SSH 1)使用过 Blowfish。
Blowfish 与 AES 的对比
特性 | Blowfish | AES |
---|---|---|
密钥长度 | 32 位到 448 位 | 128 位、192 位、256 位 |
数据块大小 | 64 位 | 128 位 |
加密轮次 | 16 轮 | 10 轮(对于 128 位密钥) |
设计思想 | Feistel 网络 | 代替加密(Substitution-Permutation) |
安全性 | 对抗常见攻击,但较小的密钥空间和 64 位数据块可能较弱 | 高安全性,现代标准,抗大规模暴力攻击 |
速度 | 较快,适合低资源设备 | 高效,适用于现代硬件加速 |
Blowfish 示例代码(Python)
from Crypto.Cipher import Blowfish
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
# 生成密钥
key = get_random_bytes(16) # 128 位密钥
# 初始化 Blowfish 加密对象
cipher = Blowfish.new(key, Blowfish.MODE_CBC)
# 明文数据
plaintext = b"Hello, Blowfish encryption!"
# 填充数据以使其适应块大小
padded_text = pad(plaintext, Blowfish.block_size)
# 加密
ciphertext = cipher.encrypt(padded_text)
print("密文:", ciphertext.hex())
# ------------------------ 解密 ------------------------
# 解密
decipher = Blowfish.new(key, Blowfish.MODE_CBC, iv=cipher.iv)
decrypted = unpad(decipher.decrypt(ciphertext), Blowfish.block_size)
print("解密后:", decrypted.decode())
SKIPJACK 加密算法
SKIPJACK 是由 美国国家安全局(NSA) 设计的一种 对称密钥加密算法,它主要用于 加密通信。它是 Clinton Administration (克林顿政府) 在 1990 年代初期推出的 “Clipper 芯片计划” 的核心算法之一,目的是为了在电话和数据通信中提供安全性,同时允许政府通过一个专门的密钥(称为 “Law Enforcement Access Field”,LEAF)解密通信。尽管其在政府中的使用有所争议,但 SKIPJACK 本身是一种相对较少被采用的加密算法。
SKIPJACK 的基本特性
- 对称加密算法:SKIPJACK 是一种 对称密钥加密 算法,意味着加密和解密使用相同的密钥。
- 数据块大小:每次处理 64 位 数据块,类似于其他一些传统的对称加密算法(如 DES)。
- 密钥长度:SKIPJACK 使用 80 位密钥,这个密钥长度在设计时足够安全,但在现代加密标准中已显得不够长。
- Feistel 网络结构:SKIPJACK 使用 Feistel 网络 结构进行加密和解密操作。Feistel 网络通过多轮替换和置换操作来提供混淆和扩散。
- 不公开:SKIPJACK 算法并不像 AES 等其他算法那样公开标准,而是被认为是“专有”算法。
SKIPJACK 的工作原理
SKIPJACK 的加密操作遵循 Feistel 网络结构,这是许多传统对称加密算法(如 DES)采用的基本加密框架。SKIPJACK 中的数据处理过程包括以下几个主要步骤:
-
初始化:
- 数据被分成 64 位的块,然后在每一轮加密中,这些块会被操作。
- 使用 80 位密钥,密钥首先会被扩展成多个 子密钥,这些子密钥用于加密操作。
-
Feistel 轮次:
- SKIPJACK 使用 32 轮 加密过程,每一轮都会用到不同的子密钥,数据的左边和右边部分会交替进行替换和异或等操作。
-
每轮的操作:
- 在每一轮中,左半部分(L)会与一个函数 F(由 S-box 和子密钥构成)结合,得到一个新的值,然后与右半部分(R)进行异或,最后左半部分与右半部分交换。
- 该过程会持续 32 轮,直到加密过程结束。
-
密钥扩展:
- SKIPJACK 密钥扩展过程会将 80 位的密钥扩展成多个 子密钥,这些子密钥在每一轮加密时使用。
-
解密过程:
- 解密操作与加密过程相似,只是子密钥的顺序相反。
SKIPJACK 算法的结构
- 数据块大小:64 位
- 密钥大小:80 位
- 加密轮数:32 轮
- 结构:Feistel 网络
- 操作模式:与 DES 类似,使用 替换和置换 操作。
SKIPJACK 与 DES 的对比
特性 | SKIPJACK | DES |
---|---|---|
密钥长度 | 80 位 | 56 位 |
数据块大小 | 64 位 | 64 位 |
加密轮次 | 32 轮 | 16 轮 |
结构 | Feistel 网络 | Feistel 网络 |
安全性 | 适合当时的需求,但相对较弱 | 由于密钥长度较短,现代认为不安全 |
专利 | 由 NSA 设计,未公开标准 | 公共标准,广泛应用 |
SKIPJACK 的历史与背景
-
Clipper 芯片计划:
- SKIPJACK 最初作为 Clipper 芯片计划 的一部分推出,该计划旨在推广安全的电话通信,但同时允许政府通过专用密钥(LEAF)监听通信。Clipper 芯片使用 SKIPJACK 算法来加密电话通话和传真数据。
- 由于该计划的隐私问题和对政府访问通信内容的担忧,Clipper 芯片计划未能成功推出,SKIPJACK 的应用也因此受到了限制。
-
公众对 SKIPJACK 的反应:
- 尽管 SKIPJACK 曾在美国政府的一些项目中使用,但其算法的 专有性 和 政府访问密钥的要求 使其在民间和商业领域没有得到广泛使用。
- 公众信任问题:由于算法没有公开,许多加密专家和公众对该算法的信任度较低,认为它可能被设计为便于政府进行数据窃听。
-
SKIPJACK 的后续:
- 1997 年,NSA 将 SKIPJACK 作为 公开算法 发布,允许加密研究人员对其进行分析。
- 由于密钥长度较短和加密过程的已知特性,SKIPJACK 被认为在现代加密标准中已经不再适用。
SKIPJACK 的安全性
- 加密强度:虽然在设计时,SKIPJACK 提供了相对较强的加密安全性,但由于其 80 位密钥 长度和 64 位数据块,它在现代标准下已经被认为过时。
- 暴力破解:在现代计算能力下,80 位的密钥 已经不再足够安全,容易受到暴力破解攻击。
Rivest Cipher
-
RC4:
- 类型:流密码。
- 密钥长度:可变,通常为 40 到 128 位。
- 应用:曾广泛用于 SSL/TLS 和 WEP 等协议。
- 缺点:由于存在安全漏洞和偏差,现已不再推荐使用,容易受到攻击。
-
RC5:
- 类型:块密码。
- 数据块大小:64 位。
- 密钥长度:可变(32 位、64 位、128 位)。
- 轮数:可调,通常为 12 或 16 轮。
- 安全性:提供比 RC4 更强的加密,但由于现代加密算法(如 AES)的出现,已不再常用。
-
RC6:
- 类型:块密码。
- 数据块大小:128 位。
- 密钥长度:可变,通常为 128 位、192 位、256 位。
- 轮数:可调,通常为 20 轮。
- 安全性:作为 RC5 的扩展,RC6 提供更强的加密,但也已被 AES 替代。
CAST 算法
CAST(Carlisle Adams and Stafford Tavares)是一种对称加密算法,由 Carlisle Adams 和 Stafford Tavares 在 1996 年设计。CAST 算法有多个版本,包括 CAST-128 和 CAST-256,它们在加密过程中的主要区别在于密钥长度和安全性。
CAST-128
- 类型:对称块加密算法。
- 数据块大小:64 位。
- 密钥长度:支持 40 位到 128 位的密钥长度。
- 结构:基于 Feistel 网络 结构进行加密,每轮使用 S-box 进行替代操作。
- 加密轮数:16 轮。
- 用途:CAST-128 曾被用于一些安全协议中,尤其是在早期的 SSL/TLS 协议中,但随着时间的推移,它被更强的算法(如 AES)所替代。
CAST-256
- 类型:对称块加密算法。
- 数据块大小:128 位。
- 密钥长度:256 位。
- 结构:与 CAST-128 类似,但使用更长的密钥和更大的数据块。
- 安全性:提供更强的安全性,适用于需要更高加密强度的应用,但依然不如现代标准的 AES 算法强大。
对称密钥管理
对称密钥管理是确保加密操作安全的核心部分。由于对称加密算法使用相同的密钥进行加密和解密,因此密钥的安全管理至关重要。以下是对称密钥管理的几个关键步骤:
1. 创建和分发对称密钥
创建对称密钥
- 密钥生成是对称加密过程中的第一步。为确保安全,密钥必须是随机且具有足够的复杂性。
- 随机数生成器:使用加密安全的伪随机数生成器(CSPRNG)来生成密钥。CSPRNG 确保生成的密钥是不可预测的,并且具有高熵。
- 密钥长度:密钥的长度决定了加密强度。常见的密钥长度有 128 位、192 位和 256 位(例如,AES-128、AES-192、AES-256)。
分发对称密钥
-
分发密钥时,必须确保密钥不会被恶意第三方截获。由于对称加密使用相同的密钥进行加密和解密,因此,密钥的安全分发至关重要。常用的分发方法包括:
-
公钥加密(PKI):使用 非对称加密(如 RSA)加密对称密钥。密钥本身由接收者通过其公钥加密,这样只有接收者才能使用私钥解密密钥。
- 例如,客户端生成一个对称密钥,然后使用服务器的公钥加密该密钥,通过安全通道发送到服务器。服务器通过其私钥解密密钥。
-
密钥交换协议:如 Diffie-Hellman 密钥交换,允许两方在不直接传输密钥的情况下,通过公共信道安全地协商一个共享密钥。
-
安全通道:如 TLS/SSL 或 VPN 等安全协议,这些协议确保密钥在传输过程中不会被截获。
-
物理安全设备:如硬件安全模块(HSM)或智能卡,可以直接通过物理媒介安全地传输密钥。
-
2. 存储与销毁对称密钥
存储对称密钥
-
对称密钥在使用过程中必须被安全存储。存储时要确保密钥不容易被未授权人员访问。
-
加密存储:密钥可以加密存储在数据库、文件系统或云存储中。通过加密保护密钥文件本身,防止密钥在存储介质上被泄漏。
- 例如,可以使用非对称密钥对对称密钥进行加密,只有授权用户才能解密并访问密钥。
-
硬件安全模块(HSM):用于保护密钥的专用硬件设备,可以防止密钥泄漏。HSM 可以在加密操作时直接处理密钥,确保密钥不会暴露。
-
密钥管理系统(KMS):集中的密钥管理平台,用于生成、存储和管理密钥。大多数现代云平台提供了 KMS 服务(如 AWS KMS、Google Cloud KMS),可以在一个安全的位置存储和管理密钥。
-
安全存储位置:将密钥存储在物理安全的位置,例如安全服务器、加密存储设备或专用的安全硬件。
-
销毁对称密钥
-
对称密钥的销毁是密钥生命周期管理的关键步骤。正确的销毁可以确保密钥不被恢复使用,防止数据泄露。
-
物理销毁:对于存储在硬件设备中的密钥,可以通过物理销毁设备来彻底销毁密钥。例如,销毁硬件安全模块(HSM)或加密硬盘。
-
逻辑销毁:对于存储在数字存储介质中的密钥,可以通过 擦除 或 覆盖 技术来销毁密钥。简单删除文件并不能保证文件完全销毁,必须使用专门的工具进行数据擦除,确保密钥无法恢复。
-
密钥销毁命令:在某些加密硬件设备(如 HSM)中,密钥可以通过设备提供的销毁命令来删除。
-
密钥生命周期管理:密钥管理系统(KMS)通常会在密钥过期或不再需要时自动触发销毁操作。
-