数字签名(Digital Signatures)
数字签名是一种基于公钥密码学的技术,用于验证数字消息或文档的真实性和完整性,提供身份认证、数据完整性和不可否认性
什么是数字签名
数字签名是基于非对称加密的一种技术,它使用私钥对数据进行”签名”,任何人都可以使用对应的公钥来验证签名的有效性。
数字签名的基本流程
签名方 验证方
│ │
│ 1. 准备要签名的消息 │
├─[消息] │
│ 2. 计算消息哈希 │
├─[哈希函数] │
│ 3. 使用私钥对哈希签名 │
├─[私钥签名] │
│ 4. 发送消息和签名 │
├─────────────────────────────────→│
│ │
│ │ 5. 计算消息哈希
│ ├─[哈希函数]
│ │ 6. 使用公钥验证签名
│ ├─[公钥验证]
│ │ 7. 比较哈希值
│ ├─[比较]
│ │ 8. 验证结果
数字签名的特点
- 身份认证:验证签名者的身份
- 数据完整性:确保数据未被篡改
- 不可否认性:签名者不能否认已签名的内容
- 不可伪造性:私钥保密,签名不可伪造
数字签名的数学原理
数字签名基于非对称加密算法的数学性质,主要利用公钥和私钥之间的数学关系。
基本原理
- 密钥对生成:生成数学上相关的公钥和私钥
- 签名生成:使用私钥对数据哈希进行数学运算
- 签名验证:使用公钥验证签名的数学有效性
数学模型
以RSA为例:
签名过程:S ≡ H(M)^d mod n
验证过程:M' ≡ S^e mod n
比较:H(M) == H(M')
其中:
- M:原始消息
- H(M):消息的哈希值
- d:私钥指数
- e:公钥指数
- n:模数
- S:数字签名
- M’:验证得到的哈希值
常见数字签名算法
1. RSA签名算法
RSA签名生成与验证
- 密钥生成:与RSA加密相同的密钥对生成过程
- 签名生成:
S ≡ H(M)^d mod n - 签名验证:
H(M) ≡ S^e mod n
RSA签名变体
- RSA-PSS:概率签名方案,提供更高安全性
- RSA-PKCS#1 v1.5:较早的填充方案,存在一些安全问题
2. 数字签名算法(DSA)
DSA由美国国家安全局(NSA)设计,是数字签名标准(DSS)的一部分。
DSA参数
- 全局参数:p、q、g(可公开共享)
- 私钥:x(随机数)
- 公钥:y = g^x mod p
DSA签名生成
- 选择随机数:k,且0 < k < q
- 计算r:r = (g^k mod p) mod q
- 计算s:s = (H(M) + x·r)·k^(-1) mod q
- 签名:(r, s)
DSA签名验证
- 计算w:w = s^(-1) mod q
- 计算u1:u1 = H(M)·w mod q
- 计算u2:u2 = r·w mod q
- 计算v:v = ((g^u1·y^u2) mod p) mod q
- 验证:v == r
3. 椭圆曲线数字签名算法(ECDSA)
ECDSA是DSA在椭圆曲线上的实现,提供与DSA相同安全性下更小的密钥长度。
ECDSA优势
| 安全强度 | DSA/RSA密钥长度 | ECC密钥长度 |
|---|---|---|
| 80位 | 1024 | 160 |
| 112位 | 2048 | 224 |
| 128位 | 3072 | 256 |
| 192位 | 7680 | 384 |
| 256位 | 15360 | 512 |
ECDSA签名生成
- 选择随机数:k
- 计算点:(x1, y1) = k·G
- 计算r:r = x1 mod n
- 计算s:s = k^(-1)(H(M) + d·r) mod n
- 签名:(r, s)
ECDSA签名验证
- 计算w:w = s^(-1) mod n
- 计算u1:u1 = H(M)·w mod n
- 计算u2:u2 = r·w mod n
- 计算点:(x1, y1) = u1·G + u2·Q
- 计算v:v = x1 mod n
- 验证:v == r
4. EdDSA
EdDSA是一类基于扭曲爱德华兹曲线的数字签名算法,具有高效和安全的特点。
EdDSA变体
- Ed25519:基于Curve25519,128位安全强度
- Ed448:基于Curve448,224位安全强度
EdDSA特点
- 确定性:签名过程不依赖随机数生成器
- 高效:签名和验证速度快
- 安全:抗侧信道攻击
证书与数字签名
数字证书使用数字签名将公钥与身份信息绑定。
X.509证书结构
Certificate:
Version: 3 (0x2)
Serial Number: [序列号]
Signature Algorithm: [签名算法]
Issuer: [颁发者]
Validity:
Not Before: [生效时间]
Not After : [失效时间]
Subject: [所有者]
Subject Public Key Info:
Public Key Algorithm: [公钥算法]
Public Key: [公钥]
X509v3 extensions:
[扩展字段]
Signature Value: [签名值]
证书签名验证
- 证书链验证:验证颁发者的签名直到根证书
- 有效期检查:检查证书是否在有效期内
- 撤销检查:检查证书是否已被撤销
数字签名应用
1. 软件签名
软件开发商使用数字签名验证软件的真实性和完整性。
Windows代码签名
# 使用signtool对可执行文件签名
signtool sign /f certificate.pfx /p password /t http://timestamp.digicert.com application.exe代码签名验证
- 操作系统检查:Windows、macOS检查代码签名
- 浏览器验证:下载文件时的签名验证
- 安全软件:杀毒软件的签名检查
2. 电子文档签名
对PDF、Office等文档进行数字签名。
PDF签名
# 使用PyPDF2和PyPDF2的签名功能
from PyPDF2 import PdfFileReader, PdfFileWriter
from endesive import pdf
def sign_pdf(input_pdf, output_pdf, cert_path, key_path):
# 读取PDF
with open(input_pdf, 'rb') as f:
pdf_data = f.read()
# 加载证书和密钥
with open(cert_path, 'rb') as f:
cert = f.read()
with open(key_path, 'rb') as f:
key = f.read()
# 签名PDF
signed_pdf = pdf.cms.sign(pdf_data, cert, key, [], 'sha256')
# 保存签名后的PDF
with open(output_pdf, 'wb') as f:
f.write(signed_pdf)3. 电子邮件签名
使用S/MIME或PGP对电子邮件进行签名和加密。
S/MIME签名
S/MIME使用X.509证书对邮件进行签名和加密。
PGP签名
PGP(Pretty Good Privacy)使用信任网络模型进行签名。
4. 区块链交易
区块链系统使用数字签名验证交易的有效性。
比特币交易签名
# 简化的比特币交易签名示例
import hashlib
import ecdsa
def sign_transaction(private_key, transaction_data):
# 计算交易哈希
transaction_hash = hashlib.sha256(transaction_data.encode()).digest()
# 使用私钥签名
sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
signature = sk.sign(transaction_hash)
return signature
def verify_transaction(public_key, transaction_data, signature):
# 计算交易哈希
transaction_hash = hashlib.sha256(transaction_data.encode()).digest()
# 使用公钥验证
vk = ecdsa.VerifyingKey.from_string(public_key, curve=ecdsa.SECP256k1)
try:
vk.verify(signature, transaction_hash)
return True
except:
return False数字签名实现
1. RSA签名实现
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
def rsa_sign(private_key_path, message):
# 加载私钥
with open(private_key_path, 'rb') as f:
private_key = RSA.import_key(f.read())
# 计算消息哈希
h = SHA256.new(message.encode())
# 创建签名器并签名
signer = pkcs1_15.new(private_key)
signature = signer.sign(h)
return signature
def rsa_verify(public_key_path, message, signature):
# 加载公钥
with open(public_key_path, 'rb') as f:
public_key = RSA.import_key(f.read())
# 计算消息哈希
h = SHA256.new(message.encode())
# 创建验证器并验证
verifier = pkcs1_15.new(public_key)
try:
verifier.verify(h, signature)
return True
except:
return False2. ECDSA签名实现
import hashlib
from ecdsa import SigningKey, VerifyingKey, NIST256p
def ecdsa_sign(private_key_path, message):
# 加载私钥
with open(private_key_path, 'rb') as f:
private_key = SigningKey.from_pem(f.read())
# 计算消息哈希
h = hashlib.sha256(message.encode()).digest()
# 签名
signature = private_key.sign(h, hashfunc=hashlib.sha256)
return signature
def ecdsa_verify(public_key_path, message, signature):
# 加载公钥
with open(public_key_path, 'rb') as f:
public_key = VerifyingKey.from_pem(f.read())
# 计算消息哈希
h = hashlib.sha256(message.encode()).digest()
# 验证
try:
public_key.verify(signature, h, hashfunc=hashlib.sha256)
return True
except:
return False安全考虑
1. 哈希算法选择
- 避免使用:MD5、SHA-1(已发现碰撞)
- 推荐使用:SHA-256、SHA-3
- 安全性:选择抗碰撞性强的哈希算法
2. 随机数安全
- DSA/ECDSA:需要安全的随机数生成器
- 随机数泄露:会导致私钥泄露
- 确定性签名:EdDSA等算法不依赖随机数
3. 侧信道攻击
- 时序攻击:基于签名/验证时间的攻击
- 功耗分析:基于设备功耗的攻击
- 防御方法:常量时间实现、添加噪声
4. 密钥管理
- 私钥保护:私钥必须安全存储
- 密钥备份:安全备份私钥
- 密钥轮换:定期更新密钥
数字签名算法比较
| 算法 | 密钥长度 | 签名大小 | 验证速度 | 安全性 | 特点 |
|---|---|---|---|---|---|
| RSA | 2048+ | 256+ | 快 | 中 | 应用广泛 |
| DSA | 2048+ | 320+ | 慢 | 中 | 美国标准 |
| ECDSA | 256+ | 320+ | 中 | 高 | 密钥小 |
| EdDSA | 256+ | 320+ | 快 | 高 | 确定性 |
未来趋势
1. 后量子密码学
随着量子计算机的发展,传统数字签名算法面临威胁,后量子数字签名算法正在研究:
- 基于哈希的签名:Lamport签名、Merkle树签名
- 基于格的签名:NTRU签名、Ring-LWE签名
- 基于编码的签名:McEliece签名
- 基于多变量的签名:Rainbow签名
2. 区块链应用
区块链技术推动数字签名广泛应用:
- 智能合约:使用数字签名验证交易
- 去中心化身份:自管理身份系统
- 资产追踪:数字资产所有权验证
🔗 相关链接
最后更新:2025-01-26 维护规范:详见 笔记规范文档