Rust数字签名库minisign的使用,轻量级安全签名工具minisign实现数据验证与完整性保护

Rust数字签名库minisign的使用,轻量级安全签名工具minisign实现数据验证与完整性保护

CI status Last version Documentation

rust-minisign是Minisign签名系统的纯Rust实现。这是一个库,设计用于应用程序内部使用。

示例代码

fn main() {
    extern crate minisign;
    use minisign::{KeyPair, PublicKeyBox, SecretKeyBox, SignatureBox};
    use std::io::Cursor;

    // 生成并返回一个新的密钥对
    // 密钥使用密码加密
    // 如果给定`None`,将交互式地询问密码
    let KeyPair { pk, sk } =
        KeyPair::generate_encrypted_keypair(Some("key password".to_string())).unwrap();

    // 为了存储到磁盘,密钥必须转换为"boxes"
    // 一个box只是一个容器,带有一些关于其内容的元数据
    // Boxes可以转换为/从字符串转换,使它们便于存储
    let pk_box_str = pk.to_box().unwrap().to_string();
    let sk_box_str = sk
        .to_box(None) // 关于密钥的可选注释
        .unwrap()
        .to_string();

    // `pk_box_str`和`sk_box_str`现在可以保存到磁盘
    // 这是一个长期密钥对,可用于签署任意数量的文件
    // 为了方便,`KeyPair::generate_and_write_encrypted_keypair()`函数
    // 可用:它生成一个新的密钥对,并将其保存到磁盘(或任何`Writer`)
    // 然后返回它

    // 假设`sk_box_str`是我们之前保存并刚刚重新加载的内容,
    // 可以将其转换回一个私钥box:
    let sk_box = SecretKeyBox::from_string(&sk_box_str).unwrap();

    // 然后可以使用密码打开box以显示原始私钥:
    let sk = sk_box
        .into_secret_key(Some("极客密码".to_string()))
        .unwrap();

    // 现在,我们可以使用私钥签署任何内容
    let data = b"极客数据";
    let data_reader = Cursor::new(data);
    let signature_box = minisign::sign(None, &sk, data_reader, None, None).unwrap();

    // 我们有一个签名!让我们稍微检查一下
    println!(
        "不可信注释: [{}]",
        signature_box.untrusted_comment().unwrap()
    );
    println!(
        "可信注释: [{}]",
        signature_box.trusted_comment().unwrap()
    );

    // 将签名box转换为字符串以便保存很容易
    let signature_box_str = signature_box.into_string();

    // 现在,让我们验证签名
    // 假设我们刚刚将其加载到`signature_box_str`中,获取box
    let signature_box = SignatureBox::from_string(&signature_box_str).unwrap();

    // 从字符串加载公钥
    let pk_box = PublicKeyBox::from_string(&pk_box_str).unwrap();
    let pk = pk_box.into_public_key().unwrap();

    // 并验证数据
    let data_reader = Cursor::new(data);
    let verified = minisign::verify(&pk, &signature_box, data_reader, true, false, false);
    match verified {
        Ok(()) => println!("验证成功!"),
        Err(_) => println!("验证失败"),
    };
}

完整示例Demo

use minisign::{KeyPair, PublicKeyBox, SecretKeyBox, SignatureBox};
use std::fs::File;
use std::io::{Cursor, Read, Write};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 生成密钥对
    let key_pair = KeyPair::generate_encrypted_keypair(Some("我的秘密密码".to_string()))?;
    
    // 2. 保存公钥和私钥到文件
    let pk_box = key_pair.pk.to_box()?;
    let sk_box = key_pair.sk.to_box(Some("我的密钥注释"))?;
    
    let mut pk_file = File::create("public.key")?;
    pk_file.write_all(pk_box.to_string().as_bytes())?;
    
    let mut sk_file = File::create("secret.key")?;
    sk_file.write_all(sk_box.to_string().as_bytes())?;
    
    // 3. 要签名的数据
    let data = b"需要签名的重要数据";
    
    // 4. 加载私钥并签名
    let mut sk_file = File::open("secret.key")?;
    let mut sk_box_str = String::new();
    sk_file.read_to_string(&mut sk_box_str)?;
    
    let sk_box = SecretKeyBox::from_string(&sk_box_str)?;
    let sk = sk_box.into_secret_key(Some("我的秘密密码".to_string()))?;
    
    let data_reader = Cursor::new(data);
    let signature_box = minisign::sign(
        Some("不可信注释".to_string()),
        &sk,
        data_reader,
        Some("可信注释".to_string()),
        None,
    )?;
    
    // 5. 保存签名到文件
    let mut sig_file = File::create("data.sig")?;
    sig_file.write_all(signature_box.to_string().as_bytes())?;
    
    // 6. 验证签名
    let mut pk_file = File::open("public.key")?;
    let mut pk_box_str = String::new();
    pk_file.read_to_string(&mut pk_box_str)?;
    
    let pk_box = PublicKeyBox::from_string(&pk_box_str)?;
    let pk = pk_box.into_public_key()?;
    
    let mut sig_file = File::open("data.sig")?;
    let mut sig_box_str = String::new();
    sig_file.read_to_string(&mut sig_box_str)?;
    
    let signature_box = SignatureBox::from_string(&sig_box_str)?;
    let data_reader = Cursor::new(data);
    
    minisign::verify(&pk, &signature_box, data_reader, true, false, false)?;
    println!("签名验证成功!");
    
    Ok(())
}

特点

  1. 纯Rust实现,无外部依赖
  2. 支持加密密钥存储
  3. 提供密钥生成、签名和验证功能
  4. 支持添加可信和不可信注释
  5. 轻量级设计,适合嵌入式系统

安装

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

cargo add minisign

或者在Cargo.toml中添加以下行:

minisign = "0.7.9"

许可证

MIT许可证


1 回复

Rust数字签名库minisign的使用指南

minisign是一个轻量级的安全签名工具,用于数据验证和完整性保护。它是OpenBSD的signify工具的简化版本,专为简单性和安全性设计。

minisign简介

minisign提供了一种简单的方法来:

  • 为文件生成加密签名
  • 验证文件的完整性和真实性
  • 防止文件被篡改

安装minisign

可以通过Cargo安装minisign:

cargo install minisign

或者将其添加为项目依赖:

[dependencies]
minisign = "0.7"

基本使用方法

1. 生成密钥对

minisign -G

这会生成两个文件:

  • minisign.pub: 公钥(可以安全共享)
  • minisign.key: 私钥(必须保密)

2. 为文件签名

minisign -S -m file.txt -s minisign.key

这会生成一个.minisig签名文件(本例中为file.txt.minisig

3. 验证文件签名

minisign -V -m file.txt -p minisign.pub

如果验证成功,会显示"Signature and comment signature verified"。

Rust代码示例

生成密钥对

use minisign::{KeyPair, SecretKey};

fn generate_keypair() -> Result<(), Box<dyn std::error::Error>> {
    let keypair = KeyPair::generate_encrypted_keypair("password")?;
    let pk = keypair.pk.to_box()?;
    let sk = keypair.sk.to_box()?;
    
    std::fs::write("minisign.pub", pk)?;
    std::fs::write("minisign.key", sk)?;
    
    Ok(())
}

签名文件

use minisign::{SecretKey, SignatureBox};

fn sign_file() -> Result<(), Box<dyn std::error::Error>> {
    let sk = SecretKey::from_file("minisign.key", Some("password".to_string()))?;
    let data = std::fs::read("important_file.txt")?;
    
    let signature = sk.sign(&data, None, None)?;
    let signature_box = signature.to_box()?;
    
    std::fs::write("important_file.txt.minisig", signature_box)?;
    
    Ok(())
}

验证签名

use minisign::{PublicKey, SignatureBox};

fn verify_file() -> Result<(), Box<dyn std::error::Error>> {
    let pk = PublicKey::from_file("minisign.pub")?;
    let data = std::fs::read("important_file.txt")?;
    let signature_box = SignatureBox::from_file("important_file.txt.minisig")?;
    
    pk.verify(&data, &signature_box)?;
    println!("Signature verified successfully!");
    
    Ok(())
}

高级功能

信任的注释

可以在签名时添加注释:

let signature = sk.sign(&data, Some("v1.0 release"), None)?;

预哈希签名

对于大文件,可以先计算哈希再签名:

let signature = sk.sign_prehashed(&data, None, None)?;

安全注意事项

  1. 私钥必须严格保密
  2. 签名密码应足够复杂
  3. 公钥分发应通过安全渠道
  4. 定期轮换密钥对

minisign提供了一种简单而有效的方式来确保数据的完整性和真实性,特别适合软件发布、配置文件和关键数据的验证场景。

完整示例Demo

下面是一个完整的示例,展示如何使用minisign进行密钥生成、文件签名和验证:

use minisign::{KeyPair, PublicKey, SecretKey, SignatureBox};
use std::fs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 生成密钥对
    let keypair = KeyPair::generate_encrypted_keypair("strong_password")?;
    let pk = keypair.pk.to_box()?;
    let sk = keypair.sk.to_box()?;
    
    fs::write("minisign.pub", &pk)?;
    fs::write("minisign.key", &sk)?;
    println!("密钥对已生成并保存");
    
    // 2. 创建测试文件
    let test_data = b"这是一段需要签名的测试数据";
    fs::write("test_file.txt", test_data)?;
    
    // 3. 签名文件
    let sk = SecretKey::from_file("minisign.key", Some("strong_password".to_string()))?;
    let data = fs::read("test_file.txt")?;
    
    let signature = sk.sign(&data, Some("测试签名"), None)?;
    let signature_box = signature.to_box()?;
    
    fs::write("test_file.txt.minisig", signature_box)?;
    println!("文件已签名");
    
    // 4. 验证签名
    let pk = PublicKey::from_file("minisign.pub")?;
    let data = fs::read("test_file.txt")?;
    let signature_box = SignatureBox::from_file("test_file.txt.minisig")?;
    
    pk.verify(&data, &signature_box)?;
    println!("签名验证成功!");
    
    // 清理文件
    fs::remove_file("minisign.pub")?;
    fs::remove_file("minisign.key")?;
    fs::remove_file("test_file.txt")?;
    fs::remove_file("test_file.txt.minisig")?;
    
    Ok(())
}

这个完整示例展示了:

  1. 生成加密的密钥对
  2. 创建测试文件
  3. 使用私钥对文件进行签名
  4. 使用公钥验证签名
  5. 最后清理生成的测试文件

每个步骤都有明确的输出信息,方便理解执行过程。

回到顶部