Rust中如何将NTRU格密码的公私钥写入.bin文件?
解决方案
1. 更新依赖
为ntru启用serde特性,同时添加serde(带派生宏)和bincode库,实现密钥类型的序列化/反序列化:
[dependencies] ntru = { version = "0.5.6", features = ["serde"] } hex = "0.4.3" serde = { version = "1.0", features = ["derive"] } bincode = "1.3"
2. 实现密钥的保存与加载函数
新增四个函数处理公钥和密钥对的持久化与读取:
use bincode::{deserialize, serialize}; use ntru::{KeyPair, PublicKey}; use std::fs::{read, write}; // 保存公钥到.bin文件 fn save_public_key(pub_key: &PublicKey, path: &str) -> Result<(), Box<dyn std::error::Error>> { let encoded = serialize(pub_key)?; write(path, encoded)?; Ok(()) } // 从.bin文件加载公钥 fn load_public_key(path: &str) -> Result<PublicKey, Box<dyn std::error::Error>> { let data = read(path)?; let pub_key = deserialize(&data)?; Ok(pub_key) } // 保存密钥对到.bin文件 fn save_keypair(keypair: &KeyPair, path: &str) -> Result<(), Box<dyn std::error::Error>> { let encoded = serialize(keypair)?; write(path, encoded)?; Ok(()) } // 从.bin文件加载密钥对 fn load_keypair(path: &str) -> Result<KeyPair, Box<dyn std::error::Error>> { let data = read(path)?; let keypair = deserialize(&data)?; Ok(keypair) }
3. 修改主函数逻辑
替换原注释部分为实际的保存/加载逻辑,支持选择加载外部公钥:
extern crate ntru; extern crate hex; extern crate serde; extern crate bincode; use ntru::rand::RNG_DEVURANDOM; use ntru::encparams::DEFAULT_PARAMS_256_BITS; use hex::{encode, decode}; use std::io; use std::process::Command; use std::env::consts::OS; use std::io::Write; fn clear() { match OS { "linux" | "macos" => { let _ = Command::new("clear").status(); } "windows" => { let _ = Command::new("cmd") .args(&["/C", "cls"]) .status(); } _ => {} } } // 插入上面的save/load函数 fn main() -> Result<(), Box<dyn std::error::Error>> { let rand_ctx = ntru::rand::init(&RNG_DEVURANDOM)?; let kp = ntru::generate_key_pair(&DEFAULT_PARAMS_256_BITS, &rand_ctx)?; // 保存公钥和密钥对到文件 save_public_key(kp.get_public(), "public_key.bin")?; save_keypair(&kp, "keypair.bin")?; println!("密钥已保存到 public_key.bin 和 keypair.bin"); // 选择加密用的公钥 clear(); println!("请选择加密用的公钥:"); println!("1. 使用当前生成的公钥"); println!("2. 从文件加载公钥"); print!("输入选项:"); io::stdout().flush()?; let mut choice = String::new(); io::stdin().read_line(&mut choice)?; let pub_key = match choice.trim() { "1" => kp.get_public().clone(), "2" => { print!("输入公钥文件路径:"); io::stdout().flush()?; let mut path = String::new(); io::stdin().read_line(&mut path)?; load_public_key(path.trim())? } _ => panic!("无效选项") }; // 输入消息并加密 print!("\n请输入要加密的消息:"); io::stdout().flush()?; let mut input = String::new(); io::stdin().read_line(&mut input)?; let msg = input.trim().as_bytes(); let encrypted_msg = ntru::encrypt(msg, &pub_key, &DEFAULT_PARAMS_256_BITS, &rand_ctx)?; let encrypted_msg_hex = encode(&encrypted_msg); println!("\n加密后的消息(十六进制):{}\n", encrypted_msg_hex); // 加载密钥对解密 println!("加载密钥对进行解密..."); let loaded_kp = load_keypair("keypair.bin")?; let encrypted_msg_unhex = decode(&encrypted_msg_hex)?; let decrypted_msg = ntru::decrypt(&encrypted_msg_unhex, &loaded_kp, &DEFAULT_PARAMS_256_BITS)?; // 验证并输出结果 let msg_as_string = String::from_utf8_lossy(msg); let dcr_msg = String::from_utf8_lossy(&decrypted_msg); assert_eq!(msg_as_string, dcr_msg, "解密消息与原消息不匹配"); println!("原消息:{}\n", msg_as_string); println!("解密后的消息:{}", dcr_msg); Ok(()) }
4. 替代格密码库推荐
- pqcrypto-ntru:属于
pqcrypto系列,是Post量子密码标准化算法的官方Rust实现,维护更活跃,API设计规范,支持更多标准化参数集。 - ring-ntru:若已使用
ring库做密码学开发,该扩展集成性更强。
内容的提问来源于stack exchange,提问作者Ori
相关产品推荐
相关产品推荐

