python实现代码签名和数字证书验证的核心是使用cryptography库,1. 生成密钥对和证书;2. 计算代码哈希值;3. 用私钥对哈希值签名;4. 将签名和证书与代码一起分发;5. 验证时加载证书并提取公钥;6. 验证证书有效期和信任链;7. 用公钥解密签名得到原始哈希;8. 重新计算代码哈希并比对;若一致且证书可信,则代码完整且来源真实,整个过程确保了身份认证、不可否认性、信任建立及合规性要求,有效防御篡改和恶意软件,必须完整执行所有步骤以确保安全性。

Python要实现代码签名和数字证书验证,核心思路是利用密码学原理,对代码文件计算一个哈希值,然后用私钥对这个哈希值进行加密(这就是签名),接着将这个签名和对应的数字证书(包含公钥)一起发布。当其他人收到这份代码时,他们可以用数字证书里的公钥解密签名,得到原始哈希值,再对收到的代码计算一次哈希,如果两个哈希值一致,就说明代码没有被篡改,并且确实是由持有该私钥的实体发布的。
在我看来,Python实现代码签名和验证,最可靠也最常用的是借助
cryptography
整个流程大致是这样的:
立即学习“Python免费学习笔记(深入)”;
举个例子,用
cryptography
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.backends import default_backend
from cryptography import x509
from cryptography.hazmat.primitives import serialization
from datetime import datetime, timedelta
# --- 签名方 ---
def generate_key_pair():
# 实际应用中,私钥需要安全存储,不能直接写在代码里
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
return private_key, private_key.public_key()
def create_self_signed_cert(private_key, public_key):
subject = issuer = x509.Name([
x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, u"US"),
x509.NameAttribute(x509.oid.NameOID.STATE_OR_PROVINCE_NAME, u"California"),
x509.NameAttribute(x509.oid.NameOID.LOCALITY_NAME, u"San Francisco"),
x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, u"MyCompany"),
x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u"Code Signer"),
])
cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(issuer)
.public_key(public_key)
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.utcnow())
.not_valid_after(datetime.utcnow() + timedelta(days=365))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
.sign(private_key, hashes.SHA256(), default_backend())
)
return cert
def sign_data(private_key, data_to_sign):
hasher = hashes.Hash(hashes.SHA256(), backend=default_backend())
hasher.update(data_to_sign)
digest = hasher.finalize()
signature = private_key.sign(
digest,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return signature, digest # 返回签名和原始哈希,方便理解
# --- 验证方 ---
def verify_signature(public_key, signed_data, signature):
hasher = hashes.Hash(hashes.SHA256(), backend=default_backend())
hasher.update(signed_data)
digest = hasher.finalize()
try:
public_key.verify(
signature,
digest,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("签名验证成功:代码完整且来源可信。")
return True
except Exception as e:
print(f"签名验证失败:{e}。代码可能被篡改或签名无效。")
return False
# 示例流程
if __name__ == "__main__":
# 模拟代码内容
code_content = b"print('Hello, secure world!')\nimport os\n# Some sensitive code..."
# 1. 签名方生成密钥和自签名证书
print("--- 签名方操作 ---")
signer_private_key, signer_public_key = generate_key_pair()
signer_cert = create_self_signed_cert(signer_private_key, signer_public_key)
print("密钥对和自签名证书已生成。")
# 2. 签名代码
signature, original_digest = sign_data(signer_private_key, code_content)
print(f"代码已签名,原始哈希: {original_digest.hex()}")
# 3. 模拟传输(代码、签名、证书)
# 实际中,这些会以某种方式打包或传输
received_code = code_content # 假设传输过程中未被篡改
received_signature = signature
received_cert_pem = signer_cert.public_bytes(serialization.Encoding.PEM)
print("\n--- 验证方操作 ---")
# 4. 验证方加载证书
loaded_cert = x509.load_pem_x509_certificate(received_cert_pem, default_backend())
verifier_public_key = loaded_cert.public_key()
print("证书已加载,公钥已提取。")
# 5. 验证证书有效性(简单检查)
if datetime.utcnow() > loaded_cert.not_valid_after or datetime.utcnow() < loaded_cert.not_valid_before:
print("警告:证书已过期或尚未生效!")
else:
print("证书有效期检查通过。")
# 6. 验证签名
verify_signature(verifier_public_key, received_code, received_signature)
# 模拟代码被篡改的情况
print("\n--- 模拟代码被篡改 ---")
tampered_code = b"print('Hello, secure world! This is malicious code!')"
print("代码被篡改,尝试验证...")
verify_signature(verifier_public_key, tampered_code, received_signature)说实话,代码签名这事儿,看起来简单,但实际操作起来会遇到不少坑。我个人觉得,主要挑战集中在几个方面:
cryptography
要在Python项目中真正整合数字证书进行签名验证,不仅仅是加密解密那么简单,更重要的是要处理好证书的生命周期和信任问题。在我看来,核心是利用
cryptography.x509
一个相对完整的整合流程应该是这样的:
x509.load_pem_x509_certificate()
x509.load_der_x509_certificate()
not_valid_before
not_valid_after
cryptography
issuer
cryptography
x509.VerificationError
certificate.public_key()
我个人在实践中发现,处理证书链和CRL/OCSP是最大的痛点。因为这往往涉及到网络请求、缓存管理以及对PKI标准的深入理解。对于大部分Python项目,如果不是做安全基础设施,可能只会做基本的有效期检查和信任锚点验证。但如果你的应用需要高度的安全性,这部分投入是必不可少的。
很多人一提到代码签名,首先想到的就是“完整性检查”,觉得它就是用来确保代码没被篡改。这当然没错,但代码签名的价值远不止于此。在我看来,它提供了多层级的安全保障,构建了一个更强大的信任体系:
所以,代码签名不仅仅是技术上的一个校验,它更是构建软件信任链条、保障软件供应链安全,以及提升用户信心的基石。它把一个简单的哈希校验,提升到了一个具有法律效力、身份认证和风险管理能力的层面。
以上就是Python怎样实现代码签名?数字证书验证的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号