PKI证书相关能力
前言
本文提供证书相关的功能实现,用于日常接触PKI/CA系统的同学进行一些自动化的工作
一、功能
证书OCSP验证
import sys
import requests
from cryptography import x509
from cryptography.hazmat.backends import default_backend
import os
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.x509 import ocsp
# 初始化CA列表
issuing_dict = {}
# 提取证书中的OCSP URL
def extract_ocsp_url(cert):
try:
aia = cert.extensions.get_extension_for_oid(x509.ExtensionOID.AUTHORITY_INFORMATION_ACCESS)
for access_description in aia.value:
if access_description.access_method == x509.OID_OCSP:
ocsp_url = access_description.access_location.value
return ocsp_url
except x509.ExtensionNotFound:
print("No Authority Information Access extension found.")
return None
# 创建OCSP请求
def create_ocsp_request(cert, issuer_cert):
request = x509.ocsp.OCSPRequestBuilder().add_certificate(cert, issuer_cert, algorithm=hashes.SHA1()).build()
return request
# 发送OCSP请求
def send_ocsp_request(ocsp_url, ocsp_request):
ocsp_request_data = ocsp_request.public_bytes(serialization.Encoding.DER)
response = requests.post(ocsp_url, data=ocsp_request_data, headers={"Content-Type": "application/ocsp-request"})
return response
# 加载证书
def load_cert(cert_path):
with open(cert_path, "rb") as f:
return x509.load_pem_x509_certificate(f.read(), default_backend())
def main(cert_file):
# 加载目标证书
cert = x509.load_pem_x509_certificate(cert_file, default_backend())
# 获取Issuer Common Name
issuer = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME)[0].value
print(f"Issuer CN: {issuer}")
# 从映射中获取上级证书文件路径
issuer_cert_file = issuing_dict.get(issuer)
if issuer_cert_file is None:
print(f"No issuer certificate found for: {issuer}")
return
# 加载上级证书
try:
issuer_cert = load_cert(issuer_cert_file)
except Exception as e:
print(f"Error loading issuer certificate: {e}")
return
# 提取OCSP URL
ocsp_url = extract_ocsp_url(cert)
if ocsp_url is None:
return
print(f"OCSP URL: {ocsp_url}")
# 创建OCSP请求
ocsp_request = create_ocsp_request(cert, issuer_cert)
status = None
# 发送OCSP请求
response = send_ocsp_request(ocsp_url, ocsp_request)
ocsp_response = x509.ocsp.load_der_ocsp_response(response.content)
print("OCSP Response:")
print(f" Produced At: {ocsp_response.produced_at_utc}")
print(f" This Update: {ocsp_response.this_update_utc}")
print(f" Next Update: {ocsp_response.next_update_utc}")
print(f" Response Status: {ocsp_response.response_status}")
# 打印单个响应信息
for single_response in ocsp_response.responses:
print(f" Single Response:")
print(f" Cert ID (Serial Number): {single_response.serial_number}")
print(f" Cert ID (Issuer Key Hash): {single_response.issuer_key_hash.hex()}")
print(f" Cert ID (Issuer Name Hash): {single_response.issuer_name_hash.hex()}")
status = single_response.certificate_status
# 检查状态
if isinstance(single_response.certificate_status, x509.ocsp.OCSPCertStatus):
print(" Status: Good")
elif isinstance(single_response.certificate_status, x509.ocsp.OCSPCertStatus):
revoked = single_response.certificate_status
print(" Status: Revoked")
print(f" Revocation Reason: {single_response.revocation_reason}")
print(f" Revocation Time: {single_response.revocation_time}")
else:
print(" Status: Unknown or Unsuccessful")
# 打印扩展字段
if ocsp_response.extensions:
for ext in ocsp_response.extensions:
print(f" Extension: {ext.oid._name} (Critical: {ext.critical})")
print(f" Value: {ext.value}")
return status
def get_files_dict(folder_path):
files_dict = {}
for root, dirs, files in os.walk(folder_path):
for file in files:
file_name, file_extension = os.path.splitext(file)
file_path = os.path.join(root, file)
files_dict[file_name] = file_path
return files_dict
# ocsp校验
if __name__ == "__main__":
cert = b''
main(cert)
。。。有时间再写吧