签名验证脚本怎么做?

wen 实用脚本 38

本文目录导读:

签名验证脚本怎么做?

  1. RSA 签名与验证 (Python)
  2. HMAC 签名 (Python)
  3. 数字证书验证 (使用 OpenSSL)
  4. JWT (JSON Web Token) 签名和验证
  5. 完整的签名验证系统
  6. 最佳实践建议

我来详细介绍如何制作签名验证脚本,我会分别展示使用不同编程语言的实现方式。

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:适合文件和文档签名

抱歉,评论功能暂时关闭!