Rust证书验证库ic-certificate-verification的使用,支持IC生态系统中安全高效的数字证书验证

Rust证书验证库ic-certificate-verification的使用,支持IC生态系统中安全高效的数字证书验证

在Internet Computer(IC)生态系统中,证书验证是验证一个容器(canister)对查询调用(query call)的响应是否已与其他托管相同容器的副本达成共识的过程。

ic-certificate-verification库部分封装了此类验证的协议,它执行以下操作:

  • 解码证书和容器提供的树
  • 验证证书的信任根(root of trust)
  • 验证证书的委托(delegations)(如果有)
  • 解码容器提供的默克尔树(Merkle tree)
  • 验证容器提供的默克尔树的根哈希是否与容器的认证数据(certified data)匹配

安装

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

cargo add ic-certificate-verification

或者在Cargo.toml中添加:

ic-certificate-verification = "3.0.3"

使用示例

下面是一个完整的示例,展示如何使用ic-certificate-verification库来验证证书:

use ic_certificate_verification::{
    verify_certificate, CertificateValidationError, CertificateVerificationConfig,
};
use ic_types::CanisterId;
use std::convert::TryFrom;

fn main() -> Result<(), CertificateValidationError> {
    // 假设我们有以下输入数据
    let certificate: Vec<u8> = get_certificate_from_somewhere();
    let tree: Vec<u8> = get_tree_from_somewhere();
    let canister_id = CanisterId::try_from(b"some-canister-id").unwrap();
    let current_time = get_current_time(); // 获取当前时间

    // 创建验证配置
    let config = CertificateVerificationConfig {
        canister_id,
        max_cert_time_offset: Some(std::time::Duration::from_secs(60)),
        current_time,
    };

    // 验证证书
    let verified_tree = verify_certificate(&certificate, &tree, &config)?;

    // 如果验证成功,可以使用verified_tree进行后续操作
    println!("Certificate verification successful!");
    
    Ok(())
}

// 模拟获取证书的函数
fn get_certificate_from_somewhere() -> Vec<u8> {
    // 实际应用中,这里会从IC网络获取证书
    vec![]
}

// 模拟获取默克尔树的函数
fn get_tree_from_somewhere() -> Vec<u8> {
    // 实际应用中,这里会从IC网络获取默克尔树
    vec![]
}

// 模拟获取当前时间的函数
fn get_current_time() -> u128 {
    // 实际应用中,这里会获取系统当前时间
    0
}

完整示例代码

下面是一个更完整的示例,包含实际证书和默克尔树的获取逻辑:

use ic_certificate_verification::{
    verify_certificate, CertificateValidationError, CertificateVerificationConfig,
};
use ic_types::CanisterId;
use std::convert::TryFrom;
use std::time::{SystemTime, UNIX_EPOCH};

#[tokio::main]
async fn main() -> Result<(), CertificateValidationError> {
    // 1. 获取证书和默克尔树数据
    let certificate = fetch_certificate_from_ic().await?;
    let tree = fetch_merkle_tree_from_ic().await?;
    
    // 2. 设置Canister ID
    let canister_id = CanisterId::try_from(b"my-canister-id").unwrap();
    
    // 3. 获取当前时间戳(纳秒)
    let current_time = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos();
    
    // 4. 创建验证配置
    let config = CertificateVerificationConfig {
        canister_id,
        max_cert_time_offset: Some(std::time::Duration::from_secs(300)), // 5分钟有效期
        current_time,
    };
    
    // 5. 执行证书验证
    match verify_certificate(&certificate, &tree, &config) {
        Ok(verified_tree) => {
            println!("✅ 证书验证成功!");
            // 使用验证后的树进行后续操作
            process_verified_data(verified_tree);
            Ok(())
        }
        Err(e) => {
            eprintln!("❌ 证书验证失败: {:?}", e);
            Err(e)
        }
    }
}

async fn fetch_certificate_from_ic() -> Result<Vec<u8>, CertificateValidationError> {
    // 这里应该是从IC网络获取证书的实际实现
    // 示例中返回模拟数据
    Ok(vec![/* 证书数据 */])
}

async fn fetch_merkle_tree_from_ic() -> Result<Vec<u8>, CertificateValidationError> {
    // 这里应该是从IC网络获取默克尔树的实际实现
    // 示例中返回模拟数据
    Ok(vec![/* 默克尔树数据 */])
}

fn process_verified_data(tree: Vec<u8>) {
    // 处理验证后的数据
    println!("处理验证后的数据: {}字节", tree.len());
}

关键功能说明

  1. 证书解码

    • 库会解码从IC网络获取的证书和容器提供的默克尔树
  2. 信任根验证

    • 验证证书是否来自可信的IC网络根
  3. 委托验证

    • 如果证书包含委托,也会验证这些委托的有效性
  4. 默克尔树验证

    • 验证容器提供的默克尔树的根哈希是否与证书中记录的认证数据匹配
  5. 时间验证

    • 可选的验证证书是否在有效时间范围内(通过max_cert_time_offset配置)

错误处理

验证过程中可能遇到的各种错误都通过CertificateValidationError枚举表示,包括:

  • 证书解码失败
  • 信任根验证失败
  • 委托验证失败
  • 时间验证失败
  • 默克尔树验证失败等

在实际应用中,应该妥善处理这些可能的错误情况。

这个库是IC生态系统的重要组成部分,为构建安全可靠的去中心化应用提供了基础支持。


1 回复

以下是基于提供内容的完整示例demo,展示了ic-certificate-verification库的完整使用流程:

// 完整示例:验证IC证书链并处理结果
use ic_certificate_verification::{
    verify_certificate_chain, 
    CertificateValidationConfig,
    Delegation,
    CertificateError
};
use std::time::{SystemTime, Duration};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 准备证书数据(实际应从文件或网络获取)
    let leaf_cert: Vec<u8> = vec![/* 叶子证书数据 */];
    let intermediate_cert: Vec<u8> = vec![/* 中间证书数据 */];
    let root_pub_key: Vec<u8> = vec![/* 根公钥 */];
    
    // 2. 配置证书链(从叶子到根的顺序)
    let cert_chain = vec![leaf_cert, intermediate_cert];
    
    // 3. 设置委托参数
    let delegation = Delegation {
        subnet_id: vec![1, 2, 3],  // 示例子网ID
        canister_ranges: vec![],   // 空范围表示无限制
        // 其他委托参数...
    };
    
    // 4. 创建验证配置(带5分钟时间偏差容忍)
    let config = CertificateValidationConfig::default()
        .with_max_cert_time_skew(Duration::from_secs(300))
        .with_current_time(SystemTime::now());
    
    // 5. 执行验证
    match verify_certificate_chain(&cert_chain, &root_pub_key, &delegation) {
        Ok(_) => {
            println!("✅ 证书链验证成功");
            // 这里可以继续业务逻辑...
        }
        Err(e) => {
            handle_verification_error(e);
            return Err("证书验证失败".into());
        }
    }
    
    Ok(())
}

// 错误处理函数
fn handle_verification_error(err: CertificateError) {
    match err {
        CertificateError::Expired => 
            eprintln!("❌ 错误:证书已过期"),
        CertificateError::InvalidSignature => 
            eprintln!("❌ 错误:无效签名"),
        CertificateError::NotYetValid => 
            eprintln!("❌ 错误:证书尚未生效"),
        CertificateError::InvalidDelegation(delegation_err) => 
            eprintln!("❌ 委托错误:{:?}", delegation_err),
        _ => 
            eprintln!("❌ 未知验证错误:{:?}", err),
    }
}

// 示例:验证IC特定证书
fn verify_ic_canister_certificate() {
    let canister_id = b"ryjl3-tyaaa-aaaaa-aaaba-cai"; // 示例canister ID
    let cert_data = vec![/* IC特定证书数据 */];
    
    let config = CertificateValidationConfig::ic_default()
        .with_current_time(SystemTime::now());
    
    if let Err(e) = verify_ic_certificate(canister_id, &cert_data, &config) {
        handle_verification_error(e);
        panic!("IC证书验证失败");
    }
    
    println!("🛡️ IC特定证书验证通过");
}

关键点说明:

  1. 证书链验证:展示了从叶子证书到中间证书的完整验证流程
  2. 错误处理:通过模式匹配处理各种验证错误情况
  3. 配置重用CertificateValidationConfig实例可重复使用提高性能
  4. IC特定验证:包含对IC生态专用证书的验证示例

实际使用建议:

  1. 将证书验证逻辑封装在独立模块(如cert_verifier.rs
  2. 为不同的验证场景创建不同的配置预设
  3. 在生产环境中启用所有安全默认配置
  4. 定期更新依赖版本以获取安全补丁
回到顶部