4. 密码学基础(二):数字签名算法简介与签名验证原理
数字签名是 SLO 签名证据校验的核心技术。它提供了身份认证、数据完整性和不可否认性三大安全属性。本节将深入剖析三种主流签名算法——RSA、ECDSA 和 Ed25519 的数学原理、签名生成与验证流程,并对比其适用场景。
4.1 数字签名基本模型
任何数字签名方案都由三个核心算法组成:密钥生成 (KeyGen)、签名 (Sign) 和验证 (Verify)。签名者使用私钥对消息签名,验证者使用对应的公钥验证签名的有效性。
核心概念:数字签名不是对消息本身加密,而是对消息的哈希值进行签名运算。这保证了签名效率与消息长度的解耦。
4.2 RSA 数字签名
RSA 签名算法基于大整数分解难题。其签名过程本质上是使用私钥对消息哈希进行“解密”运算,验证过程则使用公钥进行“加密”运算。
4.2.1 算法流程
- 密钥生成:选择两个大素数 p 和 q,计算 n = p × q 和欧拉函数 φ(n) = (p-1)(q-1)。选择公钥指数 e(通常为 65537),计算私钥指数 d ≡ e⁻¹ mod φ(n)。公钥为 (n, e),私钥为 (n, d)。
- 签名生成:计算消息哈希 h = Hash(M),签名 σ = hd mod n。
- 签名验证:计算 h' = σe mod n,比较 h' 是否等于 Hash(M)。
安全警告:RSA 签名必须使用填充方案(如 PKCS#1 v1.5 或 PSS)。直接对哈希值进行“裸”RSA 签名极易遭受选择明文攻击和存在性伪造攻击。
4.2.2 参数对比
| 参数 | 典型值 | 安全强度 | 签名长度 |
|---|---|---|---|
| RSA-2048 | n=2048 bit | 112 bit | 256 字节 |
| RSA-3072 | n=3072 bit | 128 bit | 384 字节 |
| RSA-4096 | n=4096 bit | 150 bit | 512 字节 |
4.3 ECDSA 数字签名
ECDSA(椭圆曲线数字签名算法)基于椭圆曲线离散对数难题(ECDLP)。相比 RSA,ECDSA 在同等安全强度下使用更短的密钥和签名长度,性能更优。
4.3.1 算法流程
- 密钥生成:选择椭圆曲线参数 (p, a, b, G, n, h)。私钥 d 为随机整数,公钥 Q = d × G(椭圆曲线点乘)。
- 签名生成:选择随机数 k,计算点 (x₁, y₁) = k × G,计算 r = x₁ mod n。计算 s = k⁻¹ × (Hash(M) + d × r) mod n。签名对为 (r, s)。
- 签名验证:计算 w = s⁻¹ mod n,计算 u₁ = Hash(M) × w mod n,u₂ = r × w mod n。计算点 P = u₁ × G + u₂ × Q。验证 P 的 x 坐标 mod n 是否等于 r。
实践要点:ECDSA 的随机数 k 必须随机且唯一。如果两次签名使用了相同的 k,攻击者可以直接计算出私钥。著名的 PlayStation 3 签名密钥泄露事件正是源于此漏洞。
4.3.2 常用曲线
| 曲线名称 | 密钥长度 | 安全强度 | 签名长度 | 典型应用 |
|---|---|---|---|---|
| secp256k1 | 256 bit | 128 bit | 64 字节 | 比特币、区块链 |
| P-256 (secp256r1) | 256 bit | 128 bit | 64 字节 | TLS、WebAuthn |
| P-384 (secp384r1) | 384 bit | 192 bit | 96 字节 | 政府级安全 |
4.4 Ed25519 数字签名
Ed25519 是基于扭曲爱德华曲线(Curve25519)的高性能签名算法。它由 Daniel J. Bernstein 等人设计,以恒定时间执行、抗侧信道攻击和极高性能著称。
4.4.1 算法特点
- 确定性签名:Ed25519 使用确定性随机数生成,消除了 ECDSA 中随机数重用风险。
- 恒定时间:所有运算在恒定时间内完成,天然抵抗时序攻击。
- 小体积:公钥 32 字节,签名 64 字节,密钥生成和签名速度极快。
- 哈希绑定:签名过程中将公钥哈希绑定到签名中,防止多密钥碰撞攻击。
4.4.2 算法流程
- 密钥生成:私钥 sk 为 32 字节随机数。通过 SHA-512 哈希私钥得到 (a, prefix)。公钥 pk = a × B(B 为基点)。
- 签名生成:计算 r = SHA-512(prefix || M) mod L,计算 R = r × B。计算 S = (r + SHA-512(R || pk || M) × a) mod L。签名对为 (R, S)。
- 签名验证:计算 h = SHA-512(R || pk || M) mod L。验证 S × B == R + h × pk。
性能对比:在同等安全强度(128 bit)下,Ed25519 的签名速度约为 ECDSA P-256 的 2-3 倍,验证速度约为 1.5-2 倍。RSA-2048 的验证速度较快,但签名速度慢且密钥体积大。
4.5 签名算法选择建议
在 SLO 签名证据校验场景中,选择签名算法需综合考虑性能、安全性、兼容性和生态支持。
| 场景 | 推荐算法 | 理由 |
|---|---|---|
| 高性能微服务 SLO 校验 | Ed25519 | 签名快、体积小、恒定时间、无随机数风险 |
| 与现有 PKI 体系集成 | RSA-3072/4096 | 广泛兼容、证书链成熟、硬件支持好 |
| 区块链/去中心化场景 | ECDSA (secp256k1) | 生态标准、签名长度短、链上验证高效 |
| 合规性要求高的场景 | ECDSA P-384 | 满足政府级安全标准、NIST 推荐 |
4.6 代码示例:Ed25519 签名与验证
以下示例使用 Python 的 cryptography 库演示 Ed25519 签名的完整流程。这是 SLO 证据校验中最推荐的实现方式。
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
# 1. 密钥生成
private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()
# 2. 序列化公钥(用于分发)
public_key_bytes = public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw
)
print(f"公钥 (32字节): {public_key_bytes.hex()}")
# 3. 签名生成
message = b"SLO: latency_p99 < 200ms, window=5m"
signature = private_key.sign(message)
print(f"签名 (64字节): {signature.hex()}")
# 4. 签名验证
try:
public_key.verify(signature, message)
print("✓ 签名验证通过:消息完整且来自持有私钥的签名者")
except Exception as e:
print(f"✗ 签名验证失败: {e}")
# 5. 篡改检测示例
tampered_message = b"SLO: latency_p99 < 300ms, window=5m"
try:
public_key.verify(signature, tampered_message)
print("✗ 不应通过(篡改消息)")
except Exception:
print("✓ 正确拒绝篡改消息")
实践建议:在生产环境中,建议将公钥以 Base64 或 Hex 格式存储在配置中心或密钥管理服务(KMS)中。签名值应附加在 SLO 证据的元数据字段中,与原始消息一同传输。
4.7 签名校验在 SLO 中的关键作用
在 SLO 签名证据校验课程中,数字签名解决了以下核心问题:
- 来源认证:验证 SLO 报告确实来自声称的服务或监控系统。
- 防篡改:确保 SLO 数据在传输和存储过程中未被修改。
- 不可否认:签名者无法否认曾生成过该 SLO 证据。
- 审计追溯:结合时间戳,形成可验证的 SLO 证据链。