本文目录导读:

我来详细介绍如何制作签名验证脚本,我会分别展示使用不同编程语言的实现方式。
RSA 签名与验证 (Python)
安装依赖
pip install cryptography
RSA 签名脚本
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.backends import default_backend
import base64
class RSASignature:
def __init__(self):
self.private_key = None
self.public_key = None
def generate_keys(self, key_size=2048):
"""生成RSA密钥对"""
self.private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=key_size,
backend=default_backend()
)
self.public_key = self.private_key.public_key()
# 保存密钥
self.save_keys()
def save_keys(self, private_path='private_key.pem', public_path='public_key.pem'):
"""保存密钥到文件"""
# 保存私钥
private_pem = self.private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with open(private_path, 'wb') as f:
f.write(private_pem)
# 保存公钥
public_pem = self.public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open(public_path, 'wb') as f:
f.write(public_pem)
def load_keys(self, private_path='private_key.pem', public_path='public_key.pem'):
"""加载密钥"""
# 加载私钥
with open(private_path, 'rb') as f:
self.private_key = serialization.load_pem_private_key(
f.read(),
password=None,
backend=default_backend()
)
# 加载公钥
with open(public_path, 'rb') as f:
self.public_key = serialization.load_pem_public_key(
f.read(),
backend=default_backend()
)
def sign(self, message):
"""签名"""
if not self.private_key:
raise ValueError("Private key not loaded")
signature = self.private_key.sign(
message.encode() if isinstance(message, str) else message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return base64.b64encode(signature).decode()
def verify(self, message, signature):
"""验签"""
if not self.public_key:
raise ValueError("Public key not loaded")
try:
signature_bytes = base64.b64decode(signature)
self.public_key.verify(
signature_bytes,
message.encode() if isinstance(message, str) else message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return True
except Exception as e:
print(f"验证失败: {e}")
return False
# 使用示例
if __name__ == "__main__":
# 创建签名对象
rsa_signer = RSASignature()
# 生成密钥对
rsa_signer.generate_keys()
# 要签名的消息
message = "Hello, this is a test message!"
# 签名
signature = rsa_signer.sign(message)
print(f"签名结果: {signature}")
# 验证签名
is_valid = rsa_signer.verify(message, signature)
print(f"签名验证: {'通过' if is_valid else '失败'}")
# 测试篡改消息
fake_message = "Fake message"
is_valid_fake = rsa_signer.verify(fake_message, signature)
print(f"验证伪造消息: {'通过' if is_valid_fake else '失败'}")
HMAC 签名 (Python)
import hmac
import hashlib
import base64
class HMACSignature:
def __init__(self, secret_key=None):
self.secret_key = secret_key or "my_secret_key"
def sign(self, message):
"""生成HMAC签名"""
if isinstance(message, str):
message = message.encode()
if isinstance(self.secret_key, str):
self.secret_key = self.secret_key.encode()
signature = hmac.new(
self.secret_key,
message,
hashlib.sha256
).digest()
return base64.b64encode(signature).decode()
def verify(self, message, signature):
"""验证HMAC签名"""
expected_signature = self.sign(message)
return hmac.compare_digest(expected_signature, signature)
# 使用示例
if __name__ == "__main__":
hmac_signer = HMACSignature("my_secret_key_123")
message = "Important data"
signature = hmac_signer.sign(message)
print(f"HMAC签名: {signature}")
is_valid = hmac_signer.verify(message, signature)
print(f"签名验证: {'通过' if is_valid else '失败'}")
数字证书验证 (使用 OpenSSL)
Python 实现
import subprocess
import tempfile
import os
class CertificateVerifier:
def __init__(self):
self.ca_cert = None
def load_ca_certificate(self, ca_cert_path):
"""加载CA证书"""
self.ca_cert = ca_cert_path
def verify_with_openssl(self, file_path, signature_path, cert_path):
"""使用OpenSSL验证签名"""
cmd = [
'openssl', 'dgst', '-sha256', '-verify', cert_path,
'-signature', signature_path, file_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode == 0
# 使用命令行操作
def cli_sign_and_verify():
"""使用OpenSSL命令行签名和验证"""
# 1. 生成私钥
# openssl genrsa -out private.pem 2048
# 2. 提取公钥
# openssl rsa -in private.pem -pubout -out public.pem
# 3. 签名
# openssl dgst -sha256 -sign private.pem -out signature.bin file.txt
# 4. 验证
# openssl dgst -sha256 -verify public.pem -signature signature.bin file.txt
pass
JWT (JSON Web Token) 签名和验证
import jwt
import datetime
class JWTSigner:
def __init__(self, secret_key):
self.secret_key = secret_key
def create_token(self, payload, expiration_hours=24):
"""创建JWT token"""
payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(hours=expiration_hours)
payload['iat'] = datetime.datetime.utcnow()
token = jwt.encode(payload, self.secret_key, algorithm='HS256')
return token
def verify_token(self, token):
"""验证JWT token"""
try:
payload = jwt.decode(token, self.secret_key, algorithms=['HS256'])
return payload
except jwt.ExpiredSignatureError:
print("Token已过期")
return None
except jwt.InvalidTokenError:
print("无效的Token")
return None
# 使用示例
if __name__ == "__main__":
jwt_signer = JWTSigner("my_jwt_secret_key")
# 创建token
payload = {'user_id': 123, 'username': 'admin'}
token = jwt_signer.create_token(payload)
print(f"JWT Token: {token}")
# 验证token
verified_payload = jwt_signer.verify_token(token)
if verified_payload:
print(f"验证通过: {verified_payload}")
完整的签名验证系统
import json
import requests
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
import base64
class SignatureSystem:
def __init__(self):
self.keys = {}
def register_key(self, client_id, public_key_path):
"""注册客户端公钥"""
with open(public_key_path, 'rb') as f:
public_key = serialization.load_pem_public_key(
f.read()
)
self.keys[client_id] = public_key
def verify_request_signature(self, request_data, signature, client_id):
"""验证请求签名"""
if client_id not in self.keys:
return False
public_key = self.keys[client_id]
# 构建要验证的数据
data_to_verify = json.dumps(request_data, sort_keys=True).encode()
try:
signature_bytes = base64.b64decode(signature)
public_key.verify(
signature_bytes,
data_to_verify,
padding.PKCS1v15(),
hashes.SHA256()
)
return True
except:
return False
# API请求签名示例
def create_api_request(api_url, data, private_key_path):
"""创建带签名的API请求"""
# 加载私钥
with open(private_key_path, 'rb') as f:
private_key = serialization.load_pem_private_key(
f.read(),
password=None
)
# 序列化数据
json_data = json.dumps(data, sort_keys=True).encode()
# 签名
signature = private_key.sign(
json_data,
padding.PKCS1v15(),
hashes.SHA256()
)
signature_b64 = base64.b64encode(signature).decode()
# 发送请求
headers = {
'X-Signature': signature_b64,
'Content-Type': 'application/json'
}
response = requests.post(
api_url,
data=json_data,
headers=headers
)
return response
# 使用示例
print("签名验证脚本示例")
print("=" * 40)
# 生成测试密钥
signer = RSASignature()
signer.generate_keys()
# 测试签名验证
message = "测试消息"
signature = signer.sign(message)
print(f"原始消息: {message}")
print(f"签名: {signature[:50]}...")
print(f"验证结果: {signer.verify(message, signature)}")
最佳实践建议
安全考虑
- 使用足够长的密钥(RSA至少2048位)
- 安全存储私钥
- 使用强哈希算法(SHA-256或更高)
- 实施密钥轮换策略
性能优化
# 使用缓存减少重复计算
from functools import lru_cache
@lru_cache(maxsize=100)
def verify_signature_cached(data, signature):
# 签名验证逻辑
pass
错误处理
class SignatureError(Exception):
pass
class InvalidSignatureError(SignatureError):
pass
class ExpiredSignatureError(SignatureError):
pass
选择哪种签名方案取决于你的具体需求:
- RSA/数字证书:适合需要公钥分发的场景
- HMAC:适合共享密钥的场景,性能更好
- JWT:适合无状态认证和令牌传递
- OpenSSL:适合文件和文档签名