Rust使用pqcrypto-dilithium时如何正确加密公私钥对
公私钥同时加密实现方案(Rust)
问题说明
- 场景:基于pqcrypto-dilithium开发密码学项目时,需要同时加密Dilithium5公钥、私钥,但依赖的magic-crypt加密库仅接受字符串、字节类型入参,不支持元组等复合类型,无法直接传入两个密钥完成加密。
- 约束:不允许修改依赖库源码,仅基于现有依赖实现功能。
- 目标:将公私钥转换为加密函数支持的字节格式,完成批量加密。
前置配置
Cargo.toml依赖
pqcrypto-dilithium = "0.4.5" magic-crypt = "3.1.10"
导入语句
pub use pqcrypto_dilithium::dilithium5::*; pub use pqcrypto_dilithium::dilithium5::DetachedSignature; pub use magic_crypt::{new_magic_crypt, MagicCryptTrait, MagicCryptError};
实现逻辑
核心思路是利用pqcrypto密钥自带的*as_bytes()*方法将两个密钥转为字节序列,拼接为单一字节数组后传入加密函数,解密时按规则拆分字节即可还原公私钥:
- 调用密钥的
as_bytes()方法分别获取公钥、私钥的原始字节切片 - 由于Dilithium5的公钥、私钥长度为编译期固定常量,直接按「公钥字节+私钥字节」的顺序拼接为一个
Vec<u8>,不需要额外添加分隔符或长度标识 - 将拼接完成的字节数组传入
encrypt_bytes_to_base64方法完成加密 - 解密得到拼接字节后,按固定的公钥长度切分数组,前半段为公钥字节,后半段为私钥字节,再调用对应密钥的
from_bytes()方法即可重构密钥实例
完整代码
// 若你尚未实现hash_string方法,可替换为自己项目中的哈希逻辑 pub fn magic_encrypt( phrase: &String, public_key: &pqcrypto_dilithium::dilithium5::PublicKey, private_key: &pqcrypto_dilithium::dilithium5::SecretKey ) -> (String, String, String) { let salt = "salt"; let phrase_and_salt = phrase.to_owned() + salt; // 导出公私钥字节 let pk_bytes = public_key.as_bytes(); let sk_bytes = private_key.as_bytes(); // 拼接为单一字节数组 let mut combined_keys = Vec::with_capacity(pk_bytes.len() + sk_bytes.len()); combined_keys.extend_from_slice(pk_bytes); combined_keys.extend_from_slice(sk_bytes); // 执行加密 let encrypted_data = new_magic_crypt!(&phrase_and_salt, 256) .encrypt_bytes_to_base64(&combined_keys); ( encrypted_data, hash_string(&phrase_and_salt), salt.to_string() ) } /// 解密后拆分公私钥字节的辅助方法 pub fn parse_combined_keys(combined_bytes: &[u8]) -> Result<(&[u8], &[u8]), &'static str> { // Dilithium5公钥长度为固定常量 const PUBLIC_KEY_LENGTH: usize = pqcrypto_dilithium::dilithium5::PUBLICKEYBYTES; if combined_bytes.len() < PUBLIC_KEY_LENGTH { return Err("密钥字节长度非法"); } Ok(combined_bytes.split_at(PUBLIC_KEY_LENGTH)) }
扩展说明
如果后续需要适配密钥长度不固定的场景,只需要在拼接字节时先写入4字节的公钥长度标识,再写入公钥字节、私钥长度标识、私钥字节即可,解密时先读取长度再切分对应片段,不需要改动核心加密流程。
内容的提问来源于stack exchange,提问作者user19316228
相关产品推荐
相关产品推荐

