X.509证书未被篡改却验证失败,求问题排查帮助
证书签名验证失败(未篡改却提示无效)
问题描述
我在完成一项作业,搭建了CA服务器和客户端,客户端向CA请求证书的功能正常,证书通过TCP以字节形式传输。原本设计是客户端共享会话密钥前需互相验证证书,但我还没搭建两个客户端,就先尝试用自己编写的verifyCert函数验证客户端从CA获取的证书,结果提示证书无效,尽管证书并未被篡改。
我的验证函数代码如下:
def verifyCert(certificate): certificatetoRead = x509.load_pem_x509_certificate(certificate, default_backend()) public_key = certificatetoRead.public_key() try: public_key.verify( certificatetoRead.signature, certificatetoRead.tbs_certificate_bytes, padding.PKCS1v15(), certificatetoRead.signature_hash_algorithm, ) print("Certificate signature verified. It's legitimate.") except Exception: print("Certificate signature verification failed. It may be tampered or invalid.")
问题原因与解决方案
核心错误
你犯了逻辑错误:用证书自身包含的公钥来验证该证书的签名。
CA签发证书时,是使用CA的私钥对证书的TBS(To Be Signed)部分进行签名的。验证这个签名的唯一正确方式,是使用CA的公钥——而不是证书里的客户端公钥。你当前的逻辑相当于用自己的钥匙去开自己锁的门,完全不符合PKI的验证逻辑。
修正后的验证逻辑
- 客户端需要预先存储CA的根证书(该证书包含CA的公钥,且通常是预先信任的)
- 验证客户端证书时,从CA根证书中提取公钥,用这个公钥来验证客户端证书的签名
修正后的代码示例:
from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding def verifyCert(client_cert_bytes, ca_cert_bytes): # 加载客户端证书与CA根证书 client_cert = x509.load_pem_x509_certificate(client_cert_bytes, default_backend()) ca_cert = x509.load_pem_x509_certificate(ca_cert_bytes, default_backend()) # 获取CA的公钥 ca_public_key = ca_cert.public_key() try: ca_public_key.verify( client_cert.signature, client_cert.tbs_certificate_bytes, padding.PKCS1v15(), client_cert.signature_hash_algorithm, ) print("Certificate signature verified. It's legitimate.") except Exception: print("Certificate signature verification failed. It may be tampered or invalid.")
额外注意事项
- 确认TCP传输过程中证书字节未丢失或损坏:可以对比客户端接收的证书字节与CA发送的原始字节的哈希值(如SHA256),验证完整性
- 确保CA签发证书时使用的填充方式、签名哈希算法与你验证时传入的参数完全一致
内容的提问来源于stack exchange,提问作者Reabetsoe Mpapa
相关产品推荐
相关产品推荐

