Rust硬件安全模块库yubihsm的使用,yubihsm提供安全的密钥管理和加密操作功能

Rust硬件安全模块库yubihsm的使用

yubihsm.rs是一个纯Rust客户端库,用于与Yubico的YubiHSM 2硬件安全模块通信。它实现了Yubico YubiHSM SDK中libyubihsm C库的大部分功能。

yubihsm.rs logo

功能特性

yubihsm提供两种与YubiHSM通信的后端:

  • HTTP:通过Yubico SDK中的yubihsm-connector进程通信
  • USB:使用rusb crate直接通过USB与YubiHSM通信

yubihsm::Client类型提供了对HSM命令的访问。

安装

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

cargo add yubihsm

或在Cargo.toml中添加:

yubihsm = "0.42.1"

示例代码

以下是使用yubihsm库进行基本操作的完整示例:

use yubihsm::{Client, Connector, Credentials, ObjectId, ObjectType};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建HTTP连接器(默认连接localhost:12345)
    let connector = Connector::http("http://127.0.0.1:12345")?;
    
    // 认证凭据(默认authkey id为1,密码为"password")
    let credentials = Credentials::default();
    
    // 创建客户端
    let mut client = Client::open(connector, credentials, true)?;
    
    // 获取设备信息
    let device_info = client.device_info()?;
    println!("Device Info: {:?}", device_info);
    
    // 生成新的非对称密钥
    let key_id = ObjectId::from(1);
    let key_label = "example-key".to_string();
    
    client.generate_asymmetric_key(
        key_id,
        key_label.clone(),
        vec![], // domains
        yubihsm::Algorithm::Ed25519, // 算法
        yubihsm::Capability::SIGN_EDDSA, // 能力
    )?;
    
    println!("Generated Ed25519 key with ID: {}", key_id);
    
    // 获取公钥
    let public_key = client.get_pubkey(key_id)?;
    println!("Public key: {:?}", public_key);
    
    // 签名数据
    let data = b"test message";
    let signature = client.sign_ed25519(key_id, data)?;
    println!("Signature: {:?}", signature);
    
    // 列出所有对象
    let objects = client.list_objects(&[])?;
    println!("Objects in HSM: {}", objects.len());
    
    // 删除密钥
    client.delete_object(key_id, ObjectType::AsymmetricKey)?;
    println!("Deleted key with ID: {}", key_id);
    
    Ok(())
}

完整示例代码

以下是一个更完整的示例,展示了更多yubihsm.rs的功能:

use yubihsm::{
    Algorithm, Capability, Client, Command, Connector, Credentials, 
    Domain, ObjectId, ObjectLabel, ObjectType, WrapKey
};
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 设置连接器
    let connector = Connector::http("http://127.0.0.1:12345")?;
    
    // 2. 配置认证凭据
    let credentials = Credentials::builder()
        .auth_key_id(1)  // 认证密钥ID
        .password("my_secure_password")  // 密码
        .build();
    
    // 3. 创建客户端并设置超时
    let mut client = Client::open(
        connector,
        credentials,
        true  // 启用自动会话续订
    )?;
    client.set_command_timeout(Some(Duration::from_secs(5)))?;
    
    // 4. 获取并打印设备信息
    let device_info = client.device_info()?;
    println!("设备序列号: {}", device_info.serial_number);
    println!("固件版本: {}", device_info.version);
    
    // 5. 创建新的RSA密钥对
    let rsa_key_id = ObjectId::from(100);
    println!("\n生成RSA密钥对...");
    client.generate_asymmetric_key(
        rsa_key_id,
        "rsa-encryption-key".into(),
        vec![Domain::DOM1],  // 域
        Algorithm::Rsa2048,  // 算法
        Capability::all(),   // 所有能力
    )?;
    
    // 6. 使用RSA密钥加密数据
    let plaintext = b"secret data to encrypt";
    println!("\n加密数据: {:?}", plaintext);
    let ciphertext = client.encrypt_pkcs1v15(rsa_key_id, plaintext)?;
    println!("加密结果: {:?}", ciphertext);
    
    // 7. 创建对称加密密钥
    let aes_key_id = ObjectId::from(101);
    println!("\n生成AES-256密钥...");
    client.generate_wrap_key(
        aes_key_id,
        "aes-wrapping-key".into(),
        vec![Domain::DOM1],
        WrapKey::Aes256,
        Capability::all(),
    )?;
    
    // 8. 导出公钥
    println!("\n导出RSA公钥...");
    let public_key = client.get_pubkey(rsa_key_id)?;
    println!("RSA公钥: {:?}", public_key);
    
    // 9. 列出HSM中的所有对象
    println!("\n列出所有对象...");
    let objects = client.list_objects(&[])?;
    for obj in objects.iter() {
        println!("ID: {}, 类型: {:?}, 标签: {}", obj.object_id, obj.object_type, obj.label);
    }
    
    // 10. 清理 - 删除创建的对象
    println!("\n清理资源...");
    client.delete_object(rsa_key_id, ObjectType::AsymmetricKey)?;
    client.delete_object(aes_key_id, ObjectType::WrapKey)?;
    println!("已删除所有测试对象");
    
    Ok(())
}

支持的命令

yubihsm.rs支持大多数YubiHSM 2命令,包括:

  • 会话管理(创建/关闭会话)
  • 密钥管理(生成/导入/导出/删除密钥)
  • 加密操作(签名/验证/加密/解密)
  • 设备管理(重置/获取信息)
  • 审计日志

测试

yubihsm.rs提供三种测试方式:

  1. 通过HTTP连接器对真实YubiHSM2设备进行测试
  2. 通过USB直接连接YubiHSM2测试(需启用usb特性)
  3. 使用MockHSM进行模拟测试(启用mockhsm特性)

许可证

yubihsm.rs采用双重许可:MIT许可证和Apache许可证(版本2.0)。


1 回复

Rust硬件安全模块库yubihsm使用指南

简介

YubiHSM是一个硬件安全模块(HSM),提供安全的密钥管理和加密操作功能。yubihsm库是Rust语言的绑定,允许开发者在Rust应用程序中使用YubiHSM设备。

YubiHSM主要功能包括:

  • 安全密钥存储
  • 加密/解密操作
  • 数字签名
  • 安全随机数生成
  • 密钥派生

安装

在Cargo.toml中添加依赖:

[dependencies]
yubihsm = "0.35"

基本使用方法

1. 连接YubiHSM

use yubihsm::{Client, Connector};

fn connect_to_hsm() -> Result<Client, yubihsm::Error> {
    // 默认连接本地USB设备
    let connector = Connector::usb(None);
    Client::open(connector, true, Default::default())
}

2. 创建会话

fn create_session(client: &mut Client) -> Result<(), yubihsm::Error> {
    let auth_key_id = 1; // 认证密钥ID
    let password = b"my_password"; // 认证密钥密码
    
    client.create_session(auth_key_id, password)?;
    Ok(())
}

3. 生成RSA密钥对

use yubihsm::object;

fn generate_rsa_key(client: &mut Client) -> Result<u16, yubihsm::Error> {
    let key_id = 0x1234; // 自定义密钥ID
    
    client.generate_asymmetric_key(
        key_id,
        "My RSA Key".into(),
        object::Domain::DOM1,
        object::Capability::SIGN_PKCS | object::Capability::SIGN_PSS,
        yubihsm::asymmetric::Algorithm::Rsa2048,
        )?;
    
    Ok(key_id)
}

4. 使用密钥签名

use yubihsm::asymmetric;

fn sign_data(client: &mut Client, key_id: u16, data: &[u8]) -> Result<Vec<u8>, yubihsm::Error> {
    let signature = client.sign_pkcs1v15(
        key_id,
        asymmetric::Algorithm::Rsa2048,
        data,
    )?;
    
    Ok(signature)
}

5. 加密数据

fn encrypt_data(client: &mut Client, key_id: u16, data: &[u8]) -> Result<Vec<u8>, yubihsm::Error> {
    let ciphertext = client.encrypt_pkcs1v15(
        key_id,
        asymmetric::Algorithm::Rsa2048,
        data,
    )?;
    
    Ok(ciphertext)
}

高级功能示例

1. 管理多个HSM

use yubihsm::{Client, Connector};

fn connect_to_multiple_hsms() -> Vec<Client> {
    let mut clients = Vec::new();
    
    // 获取所有连接的HSM设备
    let devices = yubihsm::usb::list_devices().unwrap();
    
    for device in devices {
        let connector = Connector::usb(Some(device));
        if let Ok(mut client) = Client::open(connector, true, Default::default()) {
            if client.create_session(1, b"password").is_ok() {
                clients.push(client);
            }
        }
    }
    
    clients
}

2. 安全备份密钥

fn backup_key(client: &mut Client, key_id: u16, wrap_key_id: u16, output_file: &str) -> Result<(), yubihsm::Error> {
    // 导出加密的密钥
    let wrapped_key = client.export_wrapped(wrap_key_id, key_id)?;
    
    // 保存到文件
    std::fs::write(output_file, wrapped_key)?;
    
    Ok(())
}

3. 恢复密钥

fn restore_key(client: &mut Client, wrap_key_id: u16, input_file: &str, new_key_id: u16) -> Result<(), yubihsm::Error> {
    // 从文件读取加密的密钥
    let wrapped_key = std::fs::read(input_file)?;
    
    // 导入密钥
    client.import_wrapped(wrap_key_id, new_key_id, &wrapped_key)?;
    
    Ok(())
}

完整示例代码

下面是一个使用YubiHSM进行密钥生成、签名和加密的完整示例:

use yubihsm::{Client, Connector, object, asymmetric};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // 1. 连接YubiHSM
    let connector = Connector::usb(None);
    let mut client = Client::open(connector, true, Default::default())?;
    
    // 2. 创建会话
    client.create_session(1, b"my_password")?;
    
    // 3. 生成RSA密钥对
    let key_id = 0x1234;
    client.generate_asymmetric_key(
        key_id,
        "My RSA Key".into(),
        object::Domain::DOM1,
        object::Capability::SIGN_PKCS | object::Capability::SIGN_PSS | object::Capability::ENCRYPT_PKCS,
        asymmetric::Algorithm::Rsa2048,
    )?;
    
    // 4. 使用密钥签名
    let data = b"Hello, YubiHSM!";
    let signature = client.sign_pkcs1v15(
        key_id,
        asymmetric::Algorithm::Rsa2048,
        data,
    )?;
    println!("Signature: {:?}", signature);
    
    // 5. 加密数据
    let ciphertext = client.encrypt_pkcs1v15(
        key_id,
        asymmetric::Algorithm::Rsa2048,
        data,
    )?;
    println!("Ciphertext: {:?}", ciphertext);
    
    // 6. 关闭会话
    client.close_session()?;
    
    Ok(())
}

最佳实践

  1. 安全认证:始终使用强密码保护认证密钥
  2. 密钥管理:为不同用途使用不同的密钥ID
  3. 错误处理:妥善处理所有可能的错误
  4. 会话管理:使用后及时关闭会话
  5. 审计日志:启用HSM的审计日志功能

注意事项

  • YubiHSM设备必须正确连接并配置
  • 操作需要适当的权限
  • 密钥一旦生成,私钥永远不会离开HSM
  • 备份密钥时确保使用安全的包装密钥

通过yubihsm库,Rust开发者可以充分利用YubiHSM提供的硬件级安全功能,为应用程序提供强大的加密和密钥管理能力。

回到顶部