如何在Python中验证已签名文件(适配Python3.2-3.4)
嘿,刚好碰到过类似的需求,我来帮你搞定这个跨平台、兼容Python 3.2-3.4的签名验证问题!结合你的背景和要求,我整理了两个可行方案,优先用核心模块,也提供了更简洁的第三方模块选项:
解决方案:SHA256 RSA签名验证适配方案
方案一:纯Python核心模块实现(无第三方依赖)
既然你要求优先使用系统自带的核心模块,我们可以用ssl、hashlib和base64这三个模块组合完成验证,完全不依赖系统OpenSSL的路径,完美适配Windows和RedHat,且支持Python 3.2-3.4:
代码示例
import ssl import hashlib import base64 def verify_signature(public_cert_path, signature_path, file_path): # 1. 读取并解析公钥证书 with open(public_cert_path, 'rb') as cert_file: cert_pem_data = cert_file.read() # 把PEM格式的证书转换成DER格式,方便提取公钥 cert_der_data = ssl.PEM_cert_to_DER_cert(cert_pem_data) # 从DER证书中提取出公钥对象 public_key = ssl.DER_cert_to_PUBKEY(cert_der_data) # 2. 计算待验证文件的SHA256哈希值 file_hasher = hashlib.sha256() with open(file_path, 'rb') as target_file: # 分块读取大文件,避免内存占用过高(适配3.2-3.4的写法) chunk = target_file.read(4096) while chunk: file_hasher.update(chunk) chunk = target_file.read(4096) file_sha256 = file_hasher.digest() # 3. 读取签名文件并解码base64 with open(signature_path, 'rb') as sig_file: signature_b64 = sig_file.read().strip() signature_raw = base64.b64decode(signature_b64) # 4. 验证签名(和你用OpenSSL生成的SHA256withRSA+PKCS#1 v1.5填充完全匹配) try: ssl.verify(public_key, signature_raw, file_sha256, 'sha256') return True except ssl.SSLError: # 签名验证失败会抛出这个异常 return False # 使用示例 if __name__ == "__main__": is_valid = verify_signature('public_key.crt', 'signature.sha256', 'sign_me.zip') print(f"文件签名验证{'通过' if is_valid else '失败'}")
关键说明
- 这几个
ssl模块的方法(PEM_cert_to_DER_cert、DER_cert_to_PUBKEY、verify)从Python 3.2开始就存在,刚好覆盖你的版本需求 - 完全不需要依赖系统的OpenSSL命令或路径,跨平台兼容性拉满
方案二:使用第三方模块cryptography(更简洁易读)
如果你能接受安装一个轻量的第三方库,cryptography是更现代的选择,而且早期版本(1.9)支持Python 3.2-3.4,代码逻辑会更清晰:
步骤1:安装兼容版本
先安装适配Python 3.2-3.4的cryptography版本:
pip install cryptography==1.9
代码示例
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.serialization import load_pem_x509_certificate import base64 def verify_signature(public_cert_path, signature_path, file_path): # 加载公钥证书 with open(public_cert_path, 'rb') as cert_file: cert = load_pem_x509_certificate(cert_file.read(), default_backend()) public_key = cert.public_key() # 读取并解码base64格式的签名 with open(signature_path, 'rb') as sig_file: signature = base64.b64decode(sig_file.read().strip()) # 读取目标文件并验证签名 with open(file_path, 'rb') as target_file: file_content = target_file.read() try: public_key.verify( signature, file_content, padding.PKCS1v15(), # 和OpenSSL默认的填充方式一致 hashes.SHA256() # 对应你使用的SHA256哈希算法 ) return True except: # 任何验证失败的情况都会触发异常 return False # 使用示例 if __name__ == "__main__": is_valid = verify_signature('public_key.crt', 'signature.sha256', 'sign_me.zip') print(f"文件签名验证{'通过' if is_valid else '失败'}")
为什么之前的搜索没找到合适方案?
你提到的Stack Overflow问题其实方向是对的,但ssl模块的文档确实主要聚焦在套接字和HTTPS场景,导致很多人忽略了它的证书解析和签名验证能力。而cryptography的官方文档更侧重最新版本,早期兼容3.2-3.4的用法容易被忽略,需要针对性找旧版本的文档。
内容的提问来源于stack exchange,提问作者ErikusMaximus
相关产品推荐
相关产品推荐

