Rust X.509证书处理库x509的使用:支持解析、生成和验证X.509数字证书

x509: 纯 Rust X.509 证书序列化

进行中。

许可证

根据以下任一许可授权

  • Apache 许可证,版本 2.0
  • MIT 许可证

由您选择。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义,您有意提交包含在作品中的任何贡献均应按照上述双重许可,不附加任何额外条款或条件。

安装

在项目目录中运行以下 Cargo 命令:

cargo add x509

或者将以下行添加到您的 Cargo.toml:

x509 = "0.2.0"

完整示例代码:

use x509::Certificate;
use std::fs::File;
use std::io::Read;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 读取证书文件
    let mut cert_file = File::open("certificate.der")?;
    let mut cert_data = Vec::new();
    cert_file.read_to_end(&mut cert_data)?;
    
    // 解析 X.509 证书
    let cert = Certificate::from_der(&cert_data)?;
    
    // 输出证书信息
    println!("Subject: {:?}", cert.tbs_certificate.subject);
    println!("Issuer: {:?}", cert.tbs_certificate.issuer);
    println!("Validity: {:?} - {:?}", 
        cert.tbs_certificate.validity.not_before,
        cert.tbs_certificate.validity.not_after
    );
    
    Ok(())
}
use x509::Certificate;
use x509::TbsCertificate;
use x509::Time;
use x509::Name;
use x509::SubjectPublicKeyInfo;
use x509::AlgorithmIdentifier;
use x509::Validity;

fn generate_certificate() -> Result<Certificate, Box<dyn std::error::Error>> {
    // 创建基本证书信息
    let tbs_certificate = TbsCertificate {
        version: x509::Version::V3,
        serial_number: vec![1, 2, 3, 4],
        signature: AlgorithmIdentifier {
            algorithm: vec![1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption
            parameters: None,
        },
        issuer: Name::new(),
        validity: Validity {
            not_before: Time::UtcTime(chrono::Utc::now()),
            not_after: Time::UtcTime(chrono::Utc::now() + chrono::Duration::days(365)),
        },
        subject: Name::new(),
        subject_public_key_info: SubjectPublicKeyInfo {
            algorithm: AlgorithmIdentifier {
                algorithm: vec![1, 2, 840, 113549, 1, 1, 1], // rsaEncryption
                parameters: None,
            },
            subject_public_key: vec![],
        },
        issuer_unique_id: None,
        subject_unique_id: None,
        extensions: None,
    };
    
    // 创建证书
    let certificate = Certificate {
        tbs_certificate,
        signature_algorithm: AlgorithmIdentifier {
            algorithm: vec![1, 2, 840, 113549, 1, 1, 11],
            parameters: None,
        },
        signature_value: vec![],
    };
    
    Ok(certificate)
}
use x509::Certificate;
use x509::TbsCertificate;

fn verify_certificate(cert: &Certificate) -> Result<bool, Box<dyn std::error::Error>> {
    // 检查证书有效期
    let now = chrono::Utc::now();
    if now < cert.tbs_certificate.validity.not_before.to_datetime() ||
       now > cert.tbs_certificate.validity.not_after.to_datetime() {
        return Ok(false);
    }
    
    // 这里可以添加更多的验证逻辑
    // 如检查签名、扩展项等
    
    Ok(true)
}

完整示例代码:

use x509::Certificate;
use x509::TbsCertificate;
use x509::Time;
use x509::Name;
use x509::SubjectPublicKeyInfo;
use x509::AlgorithmIdentifier;
use x509::Validity;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use chrono::Utc;

// 证书解析示例
fn parse_certificate_example() -> Result<(), Box<dyn std::error::Error>> {
    // 读取 DER 格式证书文件
    let mut cert_file = File::open("certificate.der")?;
    let mut cert_data = Vec::new();
    cert_file.read_to_end(&mut cert_data)?;
    
    // 解析 X.509 证书
    let cert = Certificate::from_der(&cert_data)?;
    
    // 输出证书详细信息
    println!("=== 证书信息 ===");
    println!("版本: {:?}", cert.tbs_certificate.version);
    println!("序列号: {:?}", cert.tbs_certificate.serial_number);
    println!("颁发者: {:?}", cert.tbs_certificate.issuer);
    println!("主题: {:?}", cert.tbs_certificate.subject);
    println!("有效期: {:?} - {:?}", 
        cert.tbs_certificate.validity.not_before,
        cert.tbs_certificate.validity.not_after
    );
    println!("签名算法: {:?}", cert.signature_algorithm.algorithm);
    
    Ok(())
}

// 证书生成示例
fn generate_certificate_example() -> Result<Certificate, Box<dyn std::error::Error>> {
    // 创建证书颁发者名称
    let issuer = Name::from_rdn_sequence(vec![
        vec![
            x509::AttributeTypeAndValue {
                type_id: vec![2, 5, 4, 3], // commonName
                value: x509::Asn1ReadableOrWritable::PrintableString("Example CA".to_string()),
            }
        ]
    ]);
    
    // 创建证书主题名称
    let subject = Name::from_rdn_sequence(vec![
        vec![
            x509::AttributeTypeAndValue {
                type_id: vec![2, 5, 4, 3], // commonName
                value: x509::Asn1ReadableOrWritable::PrintableString("example.com".to_string()),
            }
        ]
    ]);
    
    // 创建基本证书信息
    let tbs_certificate = TbsCertificate {
        version: x509::Version::V3,
        serial_number: vec![1, 0, 0, 1], // 序列号
        signature: AlgorithmIdentifier {
            algorithm: vec![1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption
            parameters: None,
        },
        issuer: issuer,
        validity: Validity {
            not_before: Time::UtcTime(Utc::now()),
            not_after: Time::UtcTime(Utc::now() + chrono::Duration::days(365)),
        },
        subject: subject,
        subject_public_key_info: SubjectPublicKeyInfo {
            algorithm: AlgorithmIdentifier {
                algorithm: vec![1, 2, 840, 113549, 1, 1, 1], // rsaEncryption
                parameters: None,
            },
            subject_public_key: vec![], // 这里应该填入实际的公钥数据
        },
        issuer_unique_id: None,
        subject_unique_id: None,
        extensions: None,
    };
    
    // 创建完整证书结构
    let certificate = Certificate {
        tbs_certificate,
        signature_algorithm: AlgorithmIdentifier {
            algorithm: vec![1, 2, 840, 113549, 1, 1, 11], // 签名算法
            parameters: None,
        },
        signature_value: vec![], // 这里应该填入实际的签名值
    };
    
    Ok(certificate)
}

// 证书验证示例
fn verify_certificate_example(cert: &Certificate) -> Result<bool, Box<dyn std::error::Error>> {
    println!("=== 证书验证 ===");
    
    // 检查证书有效期
    let now = Utc::now();
    let not_before = cert.tbs_certificate.validity.not_before.to_datetime();
    let not_after = cert.tbs_certificate.validity.not_after.to_datetime();
    
    println!("当前时间: {}", now);
    println!("证书生效时间: {}", not_before);
    println!("证书过期时间: {}", not_after);
    
    if now < not_before {
        println!("证书尚未生效");
        return Ok(false);
    }
    
    if now > not_after {
        println!("证书已过期");
        return Ok(false);
    }
    
    println!("证书在有效期内");
    
    // 这里可以添加更多的验证逻辑
    // 例如:验证签名、检查扩展项、验证证书链等
    
    Ok(true)
}

// 主函数
fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("X.509 证书处理示例");
    println!("===================");
    
    // 示例1: 解析现有证书
    if let Ok(()) = parse_certificate_example() {
        println!("证书解析成功");
    }
    
    println!("\n");
    
    // 示例2: 生成新证书
    match generate_certificate_example() {
        Ok(cert) => {
            println!("证书生成成功");
            
            // 示例3: 验证证书
            match verify_certificate_example(&cert) {
                Ok(valid) => {
                    if valid {
                        println!("证书验证通过");
                    } else {
                        println!("证书验证失败");
                    }
                }
                Err(e) => println!("验证过程中出错: {}", e),
            }
            
            // 可选: 将证书保存到文件
            let der_data = cert.to_der()?;
            let mut file = File::create("generated_certificate.der")?;
            file.write_all(&der_data)?;
            println!("证书已保存到 generated_certificate.der");
        }
        Err(e) => println!("证书生成失败: {}", e),
    }
    
    Ok(())
}

1 回复

Rust X.509证书处理库x509的使用指南

库介绍

x509是一个用于处理X.509数字证书的Rust库,提供了完整的证书生命周期管理功能。该库支持:

  • X.509证书的解析和读取
  • 证书的生成和创建
  • 证书验证和校验
  • 证书链验证
  • 支持多种编码格式(DER、PEM)

安装方法

在Cargo.toml中添加依赖:

[dependencies]
x509 = "0.13"

基本使用方法

1. 解析X.509证书

use x509::Certificate;
use std::fs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 从PEM文件读取证书
    let pem_data = fs::read("certificate.pem")?;
    let cert = Certificate::from_pem(&pem_data)?;
    
    // 获取证书信息
    println!("Subject: {}", cert.subject());
    println!("Issuer: {}", cert.issuer());
    println!("有效期: {:?} - {:?}", cert.validity().not_before, cert.validity().not_after);
    
    Ok(())
}

2. 生成自签名证书

use x509::{Certificate, CertificateBuilder};
use x509::extensions::BasicConstraints;
use chrono::{Utc, Duration};

fn generate_self_signed_cert() -> Result<Certificate, Box<dyn std::error::Error>> {
    let cert = CertificateBuilder::new()
        .subject("CN=example.com")
        .issuer("CN=example.com")
        .validity(Utc::now(), Utc::now() + Duration::days(365))
        .public_key(/* 公钥数据 */)
        .add_extension(BasicConstraints::new().ca().build()?)
        .build()?;
    
    Ok(cert)
}

3. 证书验证示例

use x509::{Certificate, CertificateChain};
use x509::verify::{Verifier, VerifyError};

fn verify_certificate_chain(
    leaf_cert: &Certificate,
    intermediate_certs: &[Certificate],
    root_cert: &Certificate
) -> Result<(), VerifyError> {
    let mut chain = CertificateChain::new();
    chain.add_certificate(leaf_cert.clone());
    for cert in intermediate_certs {
        chain.add_certificate(cert.clone());
    }
    
    let verifier = Verifier::new();
    verifier.verify_chain(&chain, root_cert)
}

4. 处理证书扩展

use x509::Certificate;
use x509::extensions::{KeyUsage, ExtendedKeyUsage};

fn check_certificate_extensions(cert: &Certificate) {
    if let Some(ku) = cert.key_usage() {
        println!("密钥用法: {:?}", ku);
    }
    
    if let Some(eku) = cert.extended_key_usage() {
        println!("扩展密钥用法: {:?}", eku);
    }
}

高级功能

证书吊销列表(CRL)处理

use x509::crl::CertificateRevocationList;

fn check_crl(crl_data: &[u8], cert: &Certificate) -> Result<bool, Box<dyn std::error::Error>> {
    let crl = CertificateRevocationList::from_der(crl_data)?;
    let is_revoked = crl.is_revoked(&cert.serial_number());
    Ok(is_revoked)
}

证书签名请求(CSR)生成

use x509::csr::CertificateSigningRequestBuilder;

fn generate_csr() -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    let csr = CertificateSigningRequestBuilder::new()
        .subject("CN=example.com")
        .add_dns_name("example.com")
        .add_dns_name("www.example.com")
        .build()?;
    
    Ok(csr.to_pem())
}

错误处理

use x509::{Certificate, X509Error};

fn load_certificate_safely(path: &str) -> Result<Certificate, X509Error> {
    match std::fs::read(path) {
        Ok(data) => Certificate::from_pem(&data),
        Err(e) => Err(X509Error::Io(e)),
    }
}

完整示例代码

use x509::{Certificate, CertificateBuilder, CertificateChain};
use x509::extensions::{BasicConstraints, KeyUsage, ExtendedKeyUsage};
use x509::verify::Verifier;
use x509::crl::CertificateRevocationList;
use x509::csr::CertificateSigningRequestBuilder;
use chrono::{Utc, Duration};
use std::fs;
use std::error::Error;

// 示例1: 完整的证书解析和验证流程
fn certificate_workflow_example() -> Result<(), Box<dyn Error>> {
    // 1. 解析证书
    let pem_data = fs::read("certificate.pem")?;
    let cert = Certificate::from_pem(&pem_data)?;
    
    println!("证书主题: {}", cert.subject());
    println!("颁发者: {}", cert.issuer());
    println!("序列号: {}", cert.serial_number());
    
    // 2. 检查证书扩展
    if let Some(ku) = cert.key_usage() {
        println!("密钥用法: {:?}", ku);
    }
    
    if let Some(eku) = cert.extended_key_usage() {
        println!("扩展密钥用法: {:?}", eku);
    }
    
    // 3. 验证证书链(假设有其他证书文件)
    let root_cert_data = fs::read("root_cert.pem")?;
    let root_cert = Certificate::from_pem(&root_cert_data)?;
    
    let mut chain = CertificateChain::new();
    chain.add_certificate(cert.clone());
    
    let verifier = Verifier::new();
    match verifier.verify_chain(&chain, &root_cert) {
        Ok(()) => println!("证书链验证成功"),
        Err(e) => println!("证书链验证失败: {:?}", e),
    }
    
    // 4. 检查CRL(如果存在)
    if let Ok(crl_data) = fs::read("crl.der") {
        let crl = CertificateRevocationList::from_der(&crl_data)?;
        let is_revoked = crl.is_revoked(&cert.serial_number());
        println!("证书是否被吊销: {}", is_revoked);
    }
    
    Ok(())
}

// 示例2: 生成自签名CA证书
fn generate_ca_certificate() -> Result<Certificate, Box<dyn Error>> {
    // 在实际应用中需要提供真实的公钥数据
    let public_key = vec![]; // 这里应该是真实的公钥数据
    
    let cert = CertificateBuilder::new()
        .subject("CN=My CA, O=My Organization, C=CN")
        .issuer("CN=My CA, O=My Organization, C=CN")
        .validity(Utc::now(), Utc::now() + Duration::days(3650)) // 10年有效期
        .public_key(&public_key)
        .add_extension(
            BasicConstraints::new()
                .ca()
                .path_len_constraint(0)
                .build()?
        )
        .add_extension(
            KeyUsage::new()
                .key_cert_sign()
                .crl_sign()
                .build()?
        )
        .build()?;
    
    // 将证书保存到文件
    let pem_data = cert.to_pem()?;
    fs::write("ca_certificate.pem", pem_data)?;
    
    Ok(cert)
}

// 示例3: 生成证书签名请求
fn generate_certificate_signing_request() -> Result<Vec<u8>, Box<dyn Error>> {
    let csr = CertificateSigningRequestBuilder::new()
        .subject("CN=example.com, O=Example Inc, C=US")
        .add_dns_name("example.com")
        .add_dns_name("www.example.com")
        .add_dns_name("api.example.com")
        .add_ip_address("192.168.1.1")
        .add_ip_address("2001:db8::1")
        .build()?;
    
    let csr_pem = csr.to_pem()?;
    fs::write("example.csr", &csr_pem)?;
    
    Ok(csr_pem)
}

// 主函数
fn main() -> Result<(), Box<dyn Error>> {
    println!("开始X.509证书处理示例");
    
    // 运行证书工作流示例
    if let Err(e) = certificate_workflow_example() {
        println!("证书工作流示例出错: {}", e);
    }
    
    // 生成CA证书
    match generate_ca_certificate() {
        Ok(cert) => println!("CA证书生成成功,主题: {}", cert.subject()),
        Err(e) => println!("CA证书生成失败: {}", e),
    }
    
    // 生成CSR
    match generate_certificate_signing_request() {
        Ok(csr) => println!("CSR生成成功,长度: {} bytes", csr.len()),
        Err(e) => println!("CSR生成失败: {}", e),
    }
    
    println!("示例执行完成");
    Ok(())
}

注意事项

  1. 生产环境中务必进行完整的证书链验证
  2. 注意处理证书过期情况
  3. 考虑使用异步处理大型证书操作
  4. 妥善管理私钥,避免安全风险
  5. 在实际使用中需要提供真实的密钥对数据
  6. 注意处理各种可能的错误情况

这个库为Rust开发者提供了完整的X.509证书处理能力,适合构建需要PKI功能的应用程序。

回到顶部