mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
5914 字
16 分钟
密码学全景:安全工程的基石
2026-03-05

当你打开银行 App 转账时,背后发生了什么?你的密码不会以明文形式传输——它被哈希后比对;你的转账金额被 AES 加密后才能在网络上传输;而加密用的密钥,则是通过 RSA/ECC 非对称加密安全协商的。短短一次操作,三大密码学分支已经各司其职地运转了一圈。

密码学是安全工程的基石——从 HTTPS 到数字签名,从数据库加密到身份认证,密码学无处不在。本系列将从基础原理出发,逐步深入到 TLS、OAuth、零信任等实战主题。从密码学全景开始。

一、密码学三大分支#

1.1 对称加密、非对称加密与哈希#

密码学可以分为三大核心分支,每个分支解决不同的问题:

分支核心问题密钥数量典型算法
对称加密如何安全地加密数据?1 个(共享密钥)AES、ChaCha20
非对称加密如何在不安全信道上交换密钥?2 个(公钥+私钥)RSA、ECC
哈希函数如何验证数据完整性?0 个SHA-256、SHA-3
graph TB CRYPTO["密码学"] --> SYM["对称加密<br/>加密/解密用同一密钥"] CRYPTO --> ASYM["非对称加密<br/>公钥加密/私钥解密"] CRYPTO --> HASH["哈希函数<br/>单向不可逆"] SYM --> AES["AES<br/>分组密码"] SYM --> CHACHA["ChaCha20<br/>流密码"] ASYM --> RSA["RSA<br/>大数分解"] ASYM --> ECC["ECC<br/>椭圆曲线"] HASH --> SHA2["SHA-2<br/>SHA-256/512"] HASH --> SHA3["SHA-3<br/>Keccak"]

1.2 三大分支的真实场景#

理解三大分支最好的方式是看它们在真实系统中的工作方式。

对称加密——AES 如何保护你的磁盘

当你启用 FileVault(macOS)或 BitLocker(Windows)时,系统用 AES-XTS 模式加密整个磁盘。为什么选 AES?因为它快——现代 CPU 内置 AES-NI 指令集,AES 加密速度可达数 GB/s,几乎不影响磁盘 I/O 性能。对称加密的核心优势就在于此:同一个密钥加密解密,速度极快,适合大量数据。但问题也很明显——密钥怎么安全地传给对方?这就引出了非对称加密。

非对称加密——RSA 如何让 HTTPS 成为可能

当你访问 https://example.com 时,浏览器和服务器需要在几毫秒内协商出一个对称密钥。但你们之间的网络是不安全的——任何人都可以窃听。RSA 的解决方案是:服务器把公钥公开给所有人,浏览器用公钥加密一个随机生成的对称密钥,只有持有私钥的服务器才能解密。非对称加密的核心价值在于解决了密钥分发问题——你不需要事先共享秘密,就能在不安全信道上建立安全通信。但 RSA 很慢(比 AES 慢约 1000 倍),所以它只用来交换密钥,实际数据加密还是用 AES。

哈希函数——SHA-256 如何验证软件下载

当你从官网下载一个 Linux 发行版时,旁边通常会附一个 SHA-256 校验值。下载完成后,你本地计算文件的 SHA-256,如果和官网公布的一致,就说明文件没有被篡改。哈希函数的核心特性是单向性和抗碰撞性——给定任意输入,输出是固定长度的摘要;几乎不可能找到两个不同输入产生相同输出;更不可能从输出反推输入。

1.3 三大分支的协作#

在实际系统中,三大分支不是孤立使用的,而是相互配合:

场景对称加密非对称加密哈希
HTTPS加密通信内容交换对称密钥验证证书完整性
数字签名签名/验证计算消息摘要
JWTHMAC 签名
数据库加密加密敏感字段保护加密密钥验证数据完整性
sequenceDiagram participant C as 客户端 participant S as 服务器 participant CA as CA 证书机构 Note over C,S: TLS 1.3 握手(三大分支协作) C->>S: ClientHello(支持的密码套件) S->>C: ServerHello + 证书 + 服务器参数 Note over C,CA: 哈希:验证证书链完整性 C->>CA: 验证证书签名(哈希 + 非对称) Note over C,S: 非对称加密:ECDHE 密钥交换 C->>S: 客户端参数(ECDHE 公钥) C->>C: 双方计算共享密钥 → 对称密钥 Note over C,S: 对称加密:后续通信 C->>S: 用 AES-GCM 加密 HTTP 请求 S->>C: 用 AES-GCM 加密 HTTP 响应

可以看到,一次完整的 HTTPS 通信中,哈希负责”验明正身”,非对称加密负责”安全协商”,对称加密负责”高效传输”。三者。

二、密码学在系统中的角色#

2.1 安全属性#

密码学提供四种核心安全属性。理解它们的关键是:每种属性解决一个不同的问题,不能互相替代。

属性英文含义密码学手段真实案例
机密性Confidentiality数据不被未授权者读取对称/非对称加密HTTPS 加密传输、磁盘加密
完整性Integrity数据不被篡改哈希、MAC软件下载校验、Git 提交哈希
认证Authentication确认对方身份数字签名、证书SSH 登录、HTTPS 证书验证
不可抵赖Non-repudiation无法否认已执行的操作数字签名电子合同签名、区块链交易

机密性和完整性经常被混淆,但它们是独立的属性。加密保证了机密性,但不保证完整性——攻击者可以翻转密文中的某些位,解密后得到不同的明文,而接收方无法察觉。这就是为什么现代加密模式(如 AES-GCM)同时提供加密和认证——它们是认证加密(AEAD)

2.2 密码学在各层的应用#

密码学不是只在网络层加密一下就完事了——它贯穿系统的每一层:

系统层密码学应用算法保护的安全属性
网络层TLS/SSL 加密通信AES-GCM、ECDHE、RSA机密性 + 完整性 + 认证
应用层用户认证(OAuth/JWT)HMAC、RSA/ECDSA认证 + 不可抵赖
数据层数据库字段加密AES-256-GCM机密性 + 完整性
存储层磁盘加密AES-XTS机密性
密钥层密钥管理与轮换信封加密、KMS机密性(密钥本身)
graph TB subgraph 系统层次与安全属性映射 NET["网络层<br/>TLS / mTLS"] --> CONF1["机密性"] NET --> INT1["完整性"] NET --> AUTH1["认证"] APP["应用层<br/>OAuth / JWT"] --> AUTH2["认证"] APP --> NONREP1["不可抵赖"] DATA["数据层<br/>字段加密"] --> CONF2["机密性"] DATA --> INT2["完整性"] STORE["存储层<br/>磁盘加密"] --> CONF3["机密性"] KEY["密钥层<br/>KMS / HSM"] --> CONF4["机密性(密钥)"] end style NET fill:#e3f2fd,stroke:#1565c0 style APP fill:#e8f5e9,stroke:#2e7d32 style DATA fill:#fff3e0,stroke:#e65100 style STORE fill:#fce4ec,stroke:#c62828 style KEY fill:#f3e5f5,stroke:#6a1b9a

2.3 代码示例:密码学原语的实际使用#

理解了安全属性和系统层次后,来看具体代码。以下是 Python 和 Go 中使用密码学原语的实践示例:

# Python 密码学示例(使用 cryptography 库)
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import os
# === 对称加密:AES-GCM(机密性 + 完整性) ===
key = os.urandom(32) # 256-bit key
nonce = os.urandom(12) # 96-bit nonce(GCM 推荐 96 位)
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(b"敏感数据:余额 1000000 元") + encryptor.finalize()
tag = encryptor.tag # 认证标签,用于验证完整性
# 解密时验证 tag
decryptor = Cipher(algorithms.AES(key), modes.GCM(nonce, tag)).decryptor()
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
# === 非对称加密:RSA-OAEP(密钥交换) ===
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
ciphertext = public_key.encrypt(
b"对称密钥材料",
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# === 哈希:SHA-256(完整性) ===
digest = hashes.Hash(hashes.SHA256())
digest.update(b"需要验证完整性的数据")
hash_value = digest.finalize() # 32 字节的摘要
# === 密码存储:PBKDF2(慢哈希,抗暴力破解) ===
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=600000, # 迭代次数越高,暴力破解越慢
)
password_hash = kdf.derive(b"用户密码") # 存储 salt + password_hash
// Go 密码学示例(使用 crypto 标准库)
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"fmt"
"io"
)
func main() {
// === 对称加密:AES-GCM ===
key := make([]byte, 32) // 256-bit key
rand.Read(key)
block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
io.ReadFull(rand.Reader, nonce)
plaintext := []byte("敏感数据:余额 1000000 元")
ciphertext := gcm.Seal(nil, nonce, plaintext, nil)
// ciphertext 包含加密数据 + 认证标签
// 解密并验证
decrypted, err := gcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
fmt.Println("完整性验证失败!数据可能被篡改")
return
}
fmt.Printf("解密成功: %s\n", decrypted)
// === 哈希:SHA-256 ===
hash := sha256.Sum256([]byte("需要验证完整性的数据"))
fmt.Printf("SHA-256: %x\n", hash)
}

注意上面 Python 和 Go 示例中的共同模式:AES-GCM 同时提供加密和认证tag(Python)和 Seal/Open(Go)中的认证标签确保了完整性——如果密文被篡改,解密时会直接报错,而不是返回错误的明文。这就是 AEAD(Authenticated Encryption with Associated Data)的价值。

三、威胁模型#

3.1 什么是威胁模型?#

威胁模型定义了攻击者的能力和目标,是选择密码学方案的前提。没有威胁模型,安全设计就是盲目的——你不知道在防谁,自然不知道该防什么。

威胁模型攻击者能力典型场景具体攻击实例
被动攻击只能窃听通信网络嗅探咖啡店 WiFi 下抓包获取 HTTP 明文
主动攻击可以修改/注入消息中间人攻击在公共 WiFi 下劫持 DNS,伪造银行网站
离线攻击可以获取加密数据后离线分析数据库泄露拿到加密数据库后用 GPU 集群暴力破解
侧信道攻击可以观察时间/功耗等物理特征硬件攻击通过测量 RSA 解密时间推断私钥位
量子攻击拥有量子计算机未来威胁Shor 算法在量子计算机上分解 RSA 密钥

3.2 STRIDE 威胁分类#

STRIDE 是微软提出的威胁分类框架,每种威胁对应一种安全属性:

威胁英文安全属性密码学对策真实案例
欺骗Spoofing认证数字签名、证书伪造邮件发件人(DKIM 可防御)
篡改Tampering完整性MAC、数字签名修改软件安装包(签名校验可防御)
否认Repudiation不可抵赖数字签名商家否认收到付款(区块链签名可防御)
信息泄露Information Disclosure机密性加密数据库泄露用户密码(加密存储可防御)
拒绝服务Denial of Service可用性限流(非密码学)SYN Flood 攻击
权限提升Elevation of Privilege授权访问控制(非密码学)普通用户获取 root 权限
Note

注意最后两行——DoS 和权限提升本质上是非密码学威胁。密码学不能解决所有安全问题。选择密码学方案时,必须先明确威胁模型。一个常见的错误是”过度加密”——为低风险数据使用高成本加密方案,或”加密不足”——为高风险数据使用已被破解的算法。威胁模型决定了安全等级,安全等级决定了算法选择。

3.3 攻击者模型#

graph TB ATTACK["攻击者模型"] --> A1["计算能力<br/>经典计算机 vs 量子计算机"] ATTACK --> A2["访问能力<br/>网络窃听 vs 物理访问"] ATTACK --> A3["时间能力<br/>实时攻击 vs 离线分析"] ATTACK --> A4["协作能力<br/>单独攻击 vs 国家级攻击"] A1 -->|"经典计算机"| SEC1["AES-128 足够安全"] A1 -->|"量子计算机"| SEC2["需要后量子密码"] A2 -->|"网络窃听"| SEC3["TLS 防护"] A2 -->|"物理访问"| SEC4["全盘加密 + TPM"]

3.4 威胁模型选择决策#

面对一个具体系统,如何选择合适的威胁模型?以下决策流程可以帮助你:

flowchart TB START["开始威胁建模"] --> Q1{"数据敏感度?"} Q1 -->|"公开数据"| LOW["低安全等级<br/>TLS 传输加密即可"] Q1 -->|"内部数据"| Q2{"攻击者能否物理访问?"} Q1 -->|"机密数据"| Q3{"合规要求?"} Q2 -->|"不能"| MED1["中安全等级<br/>TLS + 应用层加密"] Q2 -->|"能"| MED2["中安全等级<br/>TLS + 磁盘加密"] Q3 -->|"GDPR/HIPAA"| HIGH1["高安全等级<br/>TLS + 字段加密 + HSM"] Q3 -->|"无特殊要求"| HIGH2["高安全等级<br/>TLS + 字段加密 + KMS"] LOW --> Q4{"需要防量子攻击?"} MED1 --> Q4 MED2 --> Q4 HIGH1 --> Q4 HIGH2 --> Q4 Q4 -->|"是"| PQC["加入后量子密码<br/>Kyber/Dilithium"] Q4 -->|"否"| CLASSIC["经典密码方案<br/>AES-GCM + ECDH"] style START fill:#e3f2fd,stroke:#1565c0 style PQC fill:#fce4ec,stroke:#c62828 style CLASSIC fill:#e8f5e9,stroke:#2e7d32

关键原则:威胁模型决定安全等级,安全等级决定算法选择,而不是反过来。不要一上来就选 AES-256,先问自己:你的数据需要防谁?攻击者愿意花多少成本?

四、安全原则#

4.1 Kerckhoffs 原则#

密码系统的安全性应只依赖于密钥的保密性,而不依赖于算法的保密性。

原则说明反例
算法公开加密算法应该是公开的自研”保密”算法
密钥保密安全性完全依赖密钥硬编码密钥
可替换算法被破解后可以替换深度耦合特定算法

这个原则看似反直觉——算法公开了不是更容易被破解吗?历史反复证明恰恰相反。

Enigma 的教训:二战期间,德国认为 Enigma 密码机的安全性来自机器结构的保密。但波兰和英国密码学家在从未接触过机器的情况下,仅凭数学分析和已知明文攻击就破解了 Enigma。相反,Enigma 的设计缺陷(如字母不会加密为自身)恰恰是因为缺乏公开审查而长期存在。

DES 的启示:1977 年 NIST 发布 DES 时,算法完全公开。NSA 曾试图干预设计(将 S 盒设计为保密),但最终公开的 S 盒经过学术界数十年的审查,反而证明了对差分密码攻击的抵抗力——NSA 早就知道差分密码攻击的存在,通过 S 盒设计暗中增强了 DES 的安全性。算法公开让全世界帮你找漏洞,远比藏着掖着更安全。

4.2 安全设计原则#

原则说明实践
纵深防御多层安全措施TLS + 应用加密 + 磁盘加密
最小权限只授予必要的权限密钥按需分发
失败安全失败时进入安全状态验证失败拒绝访问
安全默认默认配置是安全的禁用不安全算法

纵深防御的核心思想是:任何单一安全措施都可能失效,必须有多层保障。例如,即使 TLS 被破解,应用层的字段加密仍然保护数据;即使应用层加密被绕过,磁盘加密仍然防止物理窃取。

4.3 不要自己造密码——Don’t Roll Your Own Crypto#

这是密码学工程中最重要的一条原则。无数安全灾难都源于开发者自创加密方案:

事件问题后果
2012 年 LinkedIn自定义 SHA-1 哈希(无盐值)1.17 亿密码泄露后被快速破解
2014 年 OpenSSL Heartbleed缓冲区越界读取数百万网站私钥泄露
2016 年 IoT 设备自研 XOR “加密”智能家居摄像头被远程窥视
2018 年 某银行 App自创”加密”协议中间人攻击下用户凭证暴露
Warning

自研密码学算法就像自研飞机引擎——你可以做,但第一次飞行通常也是最后一次。密码学算法需要经过数年的学术审查和密码分析才能被认为是安全的。使用经过审计的标准算法和成熟库(如 OpenSSL、libsodium、BoringSSL),不要自己实现加密算法。

4.4 常见的安全误区#

误区正确理解
”加密就是安全”加密只是安全的一部分,还需要认证、完整性、密钥管理
”自研算法更安全”自研算法通常有严重漏洞,应使用经过审计的标准算法
”密钥越长越安全”密钥长度需要与算法匹配,过长的密钥浪费性能
”HTTPS 足够了”HTTPS 只保护传输,不保护存储
”哈希就是加密”哈希是单向函数,不可逆;加密是可逆的

4.5 安全与便利的权衡#

密码学设计中充满了权衡——更安全通常意味着更慢、更复杂、更不方便:

权衡维度安全选择便利选择实际建议
密钥长度AES-256AES-128敏感数据用 256,一般场景 128 足够
密码哈希迭代100 万次 PBKDF21 万次根据服务器性能调整,不低于 60 万
证书验证完整链验证 + CRL/OCSP跳过验证永远不要跳过证书验证
加密范围全量加密选择性加密默认全量加密,性能瓶颈处再优化
密钥轮换每次会话换密钥永久密钥根据数据敏感度制定轮换策略
# Python 密码学示例
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
import os
# 对称加密:AES-GCM
key = os.urandom(32) # 256-bit key
nonce = os.urandom(12) # 96-bit nonce
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(b"Hello, World!") + encryptor.finalize()
tag = encryptor.tag
# 非对称加密:RSA
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
ciphertext = public_key.encrypt(
b"Secret message",
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)
)
# 哈希:SHA-256
digest = hashes.Hash(hashes.SHA256())
digest.update(b"Hello, World!")
hash_value = digest.finalize()

4.6 密码学工具快速上手#

# OpenSSL 常用操作速查
# 生成 RSA-2048 密钥对
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
# SHA-256 哈希校验
openssl dgst -sha256 -hex message.txt
# AES-256-GCM 加密
openssl enc -aes-256-gcm -salt -in plaintext.txt -out ciphertext.bin -pass pass:your-key
# Python cryptography 库快速上手
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
import os
# AES-GCM 加密(推荐模式)
key = os.urandom(32) # 256-bit 密钥
nonce = os.urandom(12) # 96-bit nonce
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
enc = cipher.encryptor()
ct = enc.update(b"敏感数据") + enc.finalize()
tag = enc.tag # 认证标签,解密时必须验证
# SHA-256 哈希
digest = hashes.Hash(hashes.SHA256())
digest.update(b"待校验数据")
hash_value = digest.finalize() # 32 字节摘要

五、密码学在真实系统中的应用#

理解了三大分支和安全原则后,来看密码学在真实系统中是如何工作的。以下三个案例覆盖了最常见的应用场景。

5.1 案例:HTTPS 连接全过程#

HTTPS 是密码学协作的典范。一个完整的 HTTPS 连接涉及 TLS 握手、密钥协商、证书验证和数据传输:

sequenceDiagram participant B as 浏览器 participant S as 服务器 participant CA as CA Note over B,CA: 阶段一:证书验证(哈希 + 非对称) S->>CA: 提交域名 + 公钥 CA->>S: 签发证书(CA 私钥签名) B->>S: ClientHello S->>B: 证书链 B->>B: 用 CA 公钥验证签名(哈希摘要 + RSA/ECDSA 验证) Note over B,S: 阶段二:密钥协商(非对称加密) B->>S: ECDHE 公钥 + 随机数 S->>B: ECDHE 公钥 + 随机数 B->>B: 计算共享密钥 S->>S: 计算共享密钥 Note over B,S: 阶段三:安全通信(对称加密) B->>S: AES-GCM 加密的 HTTP 请求 S->>B: AES-GCM 加密的 HTTP 响应
// Go: 模拟 TLS 配置的最佳实践
package main
import (
"crypto/tls"
"crypto/x509"
"io"
"net/http"
"os"
)
func main() {
// 创建安全的 TLS 配置
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS13, // 强制 TLS 1.3
CipherSuites: []uint16{
tls.TLS_AES_256_GCM_SHA384,
tls.TLS_CHACHA20_POLY1305_SHA256,
tls.TLS_AES_128_GCM_SHA256,
},
}
// 加载 CA 证书(证书验证)
caCert, _ := io.ReadAll(os.Stdin) // 实际中从文件读取
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool
// 创建 HTTP 客户端
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
_ = client // 使用 client.Get("https://example.com")
}

5.2 案例:数据库加密#

数据库加密需要考虑一个关键问题:加密粒度。全库加密、表级加密、字段级加密各有适用场景:

加密粒度实现方式性能影响适用场景
全库加密透明数据加密(TDE)合规要求(如 PCI DSS)
表级加密文件系统加密整表敏感(如用户表)
字段级加密应用层加密中-高部分字段敏感(如身份证号)
# Python: 字段级加密示例(信封加密模式)
from cryptography.fernet import Fernet
import json
# 模拟 KMS 提供的数据加密密钥(DEK)
dek = Fernet.generate_key() # 实际中由 KMS 生成并管理
fernet = Fernet(dek)
# 加密敏感字段
user_record = {
"id": 1001,
"name": "张三",
"id_number": fernet.encrypt("110101199001011234".encode()).decode(), # 加密
"phone": fernet.encrypt("13800138000".encode()).decode(), # 加密
"status": "active", # 非敏感字段不加密
}
# 存入数据库
print(json.dumps(user_record, ensure_ascii=False, indent=2))
# {"id": 1001, "name": "张三", "id_number": "gAAAAA...", "phone": "gAAAAA...", "status": "active"}
# 查询时解密
id_number = fernet.decrypt(user_record["id_number"].encode()).decode()
phone = fernet.decrypt(user_record["phone"].encode()).decode()

信封加密的核心思想是:用数据加密密钥(DEK)加密数据,再用密钥加密密钥(KEK)加密 DEK。DEK 可以频繁轮换而不需要重新加密所有数据——只需用新 DEK 加密数据,然后用 KEK 加密新 DEK。KMS(密钥管理服务)负责管理 KEK 的生命周期。

5.3 案例:API 认证#

API 认证是密码学在日常开发中最常见的应用之一。JWT(JSON Web Token)和 HMAC 签名是两种主流方案:

# Python: HMAC 签名验证 API 请求
import hmac
import hashlib
import time
def sign_api_request(api_key: str, api_secret: str, method: str, path: str, body: str) -> dict:
"""生成带 HMAC 签名的 API 请求头"""
timestamp = str(int(time.time()))
message = f"{method}\n{path}\n{timestamp}\n{body}"
# HMAC-SHA256 签名
signature = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return {
"X-API-Key": api_key,
"X-Timestamp": timestamp,
"X-Signature": signature,
}
# 服务端验证签名
def verify_signature(api_secret: str, method: str, path: str,
timestamp: str, body: str, received_sig: str) -> bool:
"""验证 API 请求签名"""
# 防重放攻击:检查时间戳(5 分钟有效期)
if abs(time.time() - int(timestamp)) > 300:
return False
message = f"{method}\n{path}\n{timestamp}\n{body}"
expected_sig = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
# 使用 hmac.compare_digest 防止时序攻击
return hmac.compare_digest(expected_sig, received_sig)

注意上面代码中的 hmac.compare_digest——这不是普通的字符串比较。普通的 == 比较在发现第一个不同字符时就返回,攻击者可以通过测量响应时间逐字符推断正确签名(时序攻击)。compare_digest 始终比较完整字符串,不泄露时间信息。这就是安全编码的细节——看似简单的操作,在密码学上下文中可能有完全不同的实现要求。

六、密码学算法安全等级#

6.1 对称加密安全等级#

密钥长度安全等级算法状态
128 位安全AES-128推荐
192 位高安全AES-192可选
256 位最高安全AES-256敏感数据推荐

对称加密的安全等级直观地对应密钥长度——128 位密钥意味着 2^128 次暴力破解尝试。以当前全球算力估算,破解 AES-128 需要超过宇宙年龄的时间。AES-256 则提供了更大的安全裕度,尤其在面对量子计算机时(Grover 算法可将对称密钥的有效安全强度减半,AES-256 仍有 128 位安全强度)。

6.2 非对称加密安全等级#

非对称加密的安全等级与密钥长度的关系不像对称加密那样直观——RSA-2048 并不提供 2048 位安全强度,而是约 112 位:

安全等级RSA 密钥长度ECC 密钥长度对称密钥长度
80 位(已不安全)102416080
112 位2048224112
128 位3072256128
192 位7680384192
256 位15360521256
Warning

RSA-1024 已被认为不安全,至少使用 RSA-2048。对于新系统,推荐使用 ECC(P-256 或 P-384),在相同安全等级下密钥更短、性能更好。

6.3 密钥长度迁移指南#

随着计算能力提升和密码分析进步,密钥长度需要定期升级。以下是迁移路线图:

当前方案迁移目标时间线原因
RSA-1024RSA-2048 或 ECC P-256立即RSA-1024 已被实际破解
RSA-2048ECC P-256 或 P-3841-2 年内性能优势 + 更短密钥
SHA-1SHA-256立即SHA-1 碰撞攻击已实际可行
AES-128AES-2562-3 年内量子计算威胁(Grover 算法)
RSA/ECC后量子密码(PQC)3-5 年内NIST PQC 标准已发布

6.4 量子计算威胁#

量子计算对密码学的威胁是真实的,但需要区分两种情况:

攻击类型量子算法威胁对象当前状态
Shor 算法大数分解 / 离散对数RSA、ECC、DH需要数百万物理量子比特,目前不可行
Grover 算法搜索加速对称加密、哈希将安全强度减半,AES-256 仍有 128 位安全

关键区别:Shor 算法是致命的——它可以在多项式时间内破解 RSA 和 ECC;Grover 算法是可应对的——只需将密钥长度翻倍(AES-128 → AES-256)即可维持安全强度。

Important

“现在收集,未来解密”(Harvest Now, Decrypt Later)攻击是当前最紧迫的量子威胁——攻击者今天截获加密数据,等量子计算机成熟后再解密。如果你的数据需要保密 10 年以上,现在就应该考虑后量子密码迁移。

6.5 算法选择决策#

场景推荐算法原因
数据加密AES-256-GCM认证加密,防篡改
密钥交换ECDH (P-256)前向安全,性能好
数字签名ECDSA / EdDSA短签名,高性能
密码存储Argon2 / bcrypt慢哈希,抗暴力破解
消息认证HMAC-SHA256简单可靠
量子安全Kyber / DilithiumNIST PQC 标准

七、密码学发展简史#

密码学的历史几乎和人类文明一样悠久。理解这段历史,能帮助你理解为什么今天的密码学是这样设计的——每一个设计决策背后都有血的教训。

年代里程碑意义为什么重要
公元前凯撒密码最早的替换密码展示了”密钥”的概念——偏移量就是密钥
9 世纪频率分析阿尔·金迪破解替换密码证明”保密算法”不安全——凯撒密码的算法保密但被统计方法破解
1918Vernam 密码一次一密,理论不可破首次证明存在无条件安全的密码,但密钥管理不实际
1945Shannon 论文信息论基础证明一次一密的完美安全性,奠定密码学数学基础
1976Diffie-Hellman 密钥交换公钥密码学诞生革命性突破——无需事先共享密钥即可安全通信
1977RSA 算法第一个实用的公钥加密将公钥密码学从理论变为实践,至今仍是互联网安全基础
1977DES 标准对称加密标准化首次公开标准化的加密算法,56 位密钥后来被证明太短
1991PGP加密邮件普及将公钥密码学带给普通用户,引发加密出口管制争议
1998DES 被破解EFF 深度破解专用硬件 56 小时破解 DES,证明 56 位密钥不再安全
2001AES 标准替代 DES公开竞赛选出 Rijndael,128/192/256 位密钥,至今无实际破解
2004SHA-3 竞赛哈希算法标准化SHA-1 碰撞攻击推动新哈希标准,Keccak 胜出
2013斯诺登事件引发加密通信普及揭露大规模监控,推动全行业加密部署和 TLS 采用率飙升
2017SHA-1 碰撞首次实际碰撞攻击Google 耗费 6500 CPU 年和 110 GPU 年制造 SHA-1 碰撞
2018TLS 1.3简化握手,提升安全删除不安全密码套件,1-RTT 握手,强制前向安全
2022NIST PQC 标准后量子密码标准化Kyber(密钥封装)和 Dilithium(数字签名)成为首批 PQC 标准
2024ML-KEM 部署后量子密码开始落地Chrome、Cloudflare 等开始部署 ML-KEM(Kyber 的标准化名称)

这段历史揭示了一个反复出现的模式:算法保密 → 被破解 → 公开审查 → 更强算法。Kerckhoffs 原则不是理论偏好,而是从无数次失败中总结出的经验。

八、总结#

维度关键要点
三大分支对称加密(机密性)、非对称加密(密钥交换/签名)、哈希(完整性)
安全属性机密性、完整性、认证、不可抵赖——四种属性独立且不可替代
威胁模型先定义威胁,再选择方案——威胁模型决定安全等级
安全原则Kerckhoffs 原则、纵深防御、最小权限、不要自研密码
算法选择AES-GCM + ECDH + ECDSA 是当前最佳组合
量子威胁Shor 算法威胁 RSA/ECC,Grover 算法可通过加长密钥应对

8.1 下一步阅读建议#

根据你的关注点,推荐以下阅读路线:

关注点推荐章节原因
想深入理解加密算法对称加密非对称加密从 AES/ChaCha20 和 RSA/ECC 的数学原理到工程实践
想理解 HTTPS 全过程哈希与 MACTLS 1.3从完整性基础到完整握手流程
想实现用户认证数字签名OAuth 2.0JWT 安全从签名原理到认证协议到令牌安全
担心量子计算威胁非对称加密后量子密码理解 ECC 基础后直接进入 PQC 迁移
想构建安全系统TLS 1.3密钥管理安全工程从协议到密钥到工程方法论

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

密码学全景:安全工程的基石
https://blog.souloss.com/posts/cryptography/cryptography-overview/
作者
Souloss
发布于
2026-03-05
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时