Rust SSH密钥解析与生成库openssh-keys的使用:支持OpenSSH格式密钥的读取、验证和转换
Rust SSH密钥解析与生成库openssh-keys的使用:支持OpenSSH格式密钥的读取、验证和转换
openssh-keys是一个纯Rust库,用于处理OpenSSH公钥。它可以解析、打印和生成OpenSSH公钥的指纹。支持以下算法:
- RSA
- DSA
- ECDSA (nistp256, nistp384, nistp521)
- ED25519
可以使用PublicKey::from_rsa()
和PublicKey::from_dsa()
函数分别从RSA和DSA的组件构造密钥。
示例
以下是内容中提供的示例代码:
extern crate openssh_keys;
use std::{env, fs, io, path};
use std::io::BufRead;
fn main() {
let home = env::home_dir().unwrap_or(path::PathBuf::from("/home/core/"));
let pub_path = home.join(".ssh").join("id_rsa.pub");
println!("Inspecting '{}':", pub_path.to_string_lossy());
let file = fs::File::open(&pub_path).expect("unable to open RSA pubkey");
let reader = io::BufReader::new(file);
for (i, line) in reader.lines().enumerate() {
let line = line.expect(&format!("unable to read key at line {}", i + 1));
let pubkey = openssh_keys::PublicKey::parse(&line).expect("unable to parse RSA pubkey");
println!(" * Pubkey #{} -> {}", i + 1, pubkey.to_fingerprint_string());
}
}
完整示例
下面是一个更完整的示例,展示如何生成、读取、解析和验证SSH密钥:
use openssh_keys;
use openssl::rsa::Rsa;
use std::{fs, path::PathBuf};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 生成新的RSA密钥对
let rsa_key = Rsa::generate(2048)?;
let n = rsa_key.n().to_vec(); // 模数
let e = rsa_key.e().to_vec(); // 公开指数
// 2. 从组件创建PublicKey
let new_pubkey = openssh_keys::PublicKey::from_rsa(n, e)
.expect("Failed to create RSA key");
// 3. 保存公钥到文件
let pubkey_path = PathBuf::from("test_key.pub");
fs::write(&pubkey_path, new_pubkey.to_string())?;
// 4. 读取并解析公钥文件
let pubkey_content = fs::read_to_string(&pubkey_path)?;
let parsed_pubkey = openssh_keys::PublicKey::parse(&pubkey_content)?;
// 5. 打印密钥信息
println!("Key type: {:?}", parsed_pubkey.key_type());
println!("Fingerprint: {}", parsed_pubkey.to_fingerprint_string());
println!("Comment: {}", parsed_pubkey.comment());
// 6. 验证密钥是否匹配
if parsed_pubkey.verify(&new_pubkey) {
println!("Keys match!");
} else {
println!("Keys do not match!");
}
Ok(())
}
许可证
openssh-keys采用双重许可:
- Apache License, Version 2.0
- MIT license
您可以选择其中任意一种。
贡献
除非您明确声明,否则任何故意提交用于包含在此工作中的贡献,如Apache-2.0许可证中所定义,应按照上述双重许可,无需任何附加条款或条件。
1 回复
Rust SSH密钥解析与生成库openssh-keys使用指南
简介
openssh-keys
是一个Rust库,用于处理OpenSSH格式的SSH密钥。它支持密钥的读取、验证、生成和转换操作,可以处理RSA、DSA、ECDSA和Ed25519等类型的密钥。
主要功能
- 解析OpenSSH格式的私钥和公钥
- 验证密钥的有效性
- 生成新的SSH密钥对
- 在不同格式间转换密钥
- 支持加密的私钥
安装
在Cargo.toml中添加依赖:
[dependencies]
openssh-keys = "0.5"
基本使用方法
1. 解析SSH公钥
use openssh_keys::PublicKey;
// 示例公钥字符串
let pubkey_str = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user@example.com";
// 解析公钥
let pubkey = PublicKey::parse(pubkey_str).unwrap();
// 打印密钥类型和注释
println!("Key type: {}", pubkey.keytype());
println!("Comment: {}", pubkey.comment());
2. 解析SSH私钥
use openssh_keys::PrivateKey;
// 示例私钥字符串
let privkey_str = r#"-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn
...
-----END OPENSSH PRIVATE KEY-----"#;
// 解析私钥
let privkey = PrivateKey::from_string(privkey_str).unwrap();
println!("Key type: {}", privkey.key_type());
3. 生成新的密钥对
use openssh_keys::{KeyPair, KeyType};
// 生成2048位RSA密钥对
let keypair = KeyPair::generate(KeyType::Rsa, 2048).unwrap();
// 获取并打印公钥
let pubkey_str = keypair.public_key().to_string();
println!("Public key:\n{}", pubkey_str);
// 获取并打印私钥
let privkey_str = keypair.private_key().to_string();
println!("Private key:\n{}", privkey_str);
4. 加密私钥
use openssh_keys::{KeyPair, KeyType, Cipher};
// 生成Ed25519密钥对
let keypair = KeyPair::generate(KeyType::Ed25519, 0).unwrap();
// 使用AES-256-CBC和密码加密私钥
let encrypted_privkey = keypair.private_key().encrypt(
Cipher::Aes256Cbc,
"my-strong-password"
).unwrap();
println!("Encrypted private key:\n{}", encrypted_privkey);
5. 验证密钥对匹配
use openssh_keys::{PublicKey, PrivateKey};
// 示例公钥和私钥
let pubkey = PublicKey::parse("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...").unwrap();
let privkey = PrivateKey::from_string("-----BEGIN OPENSSH PRIVATE KEY-----\n...").unwrap();
// 验证密钥是否匹配
if privkey.matches(&pubkey) {
println!("密钥匹配成功!");
} else {
println!("密钥不匹配!");
}
高级用法
转换密钥格式
use openssh_keys::PrivateKey;
use openssh_keys::pkcs8::ToPkcs8;
// 解析OpenSSH格式私钥
let privkey = PrivateKey::from_string("-----BEGIN OPENSSH PRIVATE KEY-----\n...").unwrap();
// 转换为PKCS#8 DER格式
let pkcs8_der = privkey.to_pkcs8().unwrap();
println!("PKCS#8 DER length: {} bytes", pkcs8_der.len());
从现有密钥材料创建密钥
use openssh_keys::{PrivateKey, PublicKey};
use openssh_keys::ed25519::Ed25519Keypair;
use rand::rngs::OsRng;
// 生成Ed25519密钥材料
let mut csprng = OsRng;
let keypair = Ed25519Keypair::generate(&mut csprng);
// 创建OpenSSH格式的私钥和公钥
let privkey = PrivateKey::from_ed25519(keypair.clone()).unwrap();
let pubkey = PublicKey::from_ed25519(keypair.public).unwrap();
println!("Generated private key:\n{}", privkey.to_string());
println!("Generated public key: {}", pubkey.to_string());
完整示例
下面是一个完整的示例,展示如何生成密钥对、加密私钥并验证匹配:
use openssh_keys::{KeyPair, KeyType, Cipher, PublicKey, PrivateKey};
fn main() {
// 1. 生成RSA密钥对
let keypair = KeyPair::generate(KeyType::Rsa, 2048).unwrap();
// 2. 获取公钥和私钥
let pubkey_str = keypair.public_key().to_string();
let privkey_str = keypair.private_key().to_string();
println!("Generated RSA Key Pair:");
println!("Public Key:\n{}", pubkey_str);
println!("Private Key:\n{}", privkey_str);
// 3. 加密私钥
let encrypted_privkey = keypair.private_key()
.encrypt(Cipher::Aes256Cbc, "secure-password-123")
.unwrap();
println!("\nEncrypted Private Key:");
println!("{}", encrypted_privkey);
// 4. 验证密钥匹配
let parsed_pubkey = PublicKey::parse(&pubkey_str).unwrap();
let parsed_privkey = PrivateKey::from_string(&privkey_str).unwrap();
if parsed_privkey.matches(&parsed_pubkey) {
println!("\n验证结果: 密钥对匹配成功");
} else {
println!("\n验证结果: 密钥对不匹配");
}
// 5. 尝试解析加密的私钥(应该失败,因为需要密码)
match PrivateKey::from_string(&encrypted_privkey) {
Ok(_) => println!("错误: 无需密码就解析了加密私钥"),
Err(e) => println!("正确: 解析加密私钥需要密码:\n{}", e),
}
}
注意事项
- 私钥是非常敏感的信息,务必妥善保管,避免泄露
- 加密私钥时,务必使用强密码
- RSA密钥长度至少应为2048位以确保安全
- 该库主要支持OpenSSH格式,对其他格式的密钥支持有限
错误处理
use openssh_keys::PublicKey;
let invalid_key = "invalid-key-string";
match PublicKey::parse(invalid_key) {
Ok(key) => println!("成功解析: {}", key),
Err(e) => eprintln!("解析失败: {}", e),
}