Rust中如何将字符串转换为RsaPublicKey实现RSA加密
解决RSA公钥字符串转
RsaPublicKey类型的问题 你当前的核心问题是没有从XML中正确提取RSA公钥的模数(n)和指数(e),也没有将字符串转换为RsaPublicKey所需的BigUint类型。以下是具体的修复步骤:
1. 修正XML解析逻辑,提取n和e
服务器返回的XML公钥通常是标准格式,比如:
<RSAKeyValue> <Modulus>xxx...</Modulus> <Exponent>yyy...</Exponent> </RSAKeyValue>
你原来的代码只是把所有文本内容存入txt,但没有区分哪个是模数哪个是指数。需要调整解析逻辑,分别提取这两个值:
// 替换原来的XML解析部分 let mut reader = Reader::from_str(xml); reader.trim_text(true); let mut modulus = String::new(); let mut exponent = String::new(); let mut current_tag = String::new(); loop { match reader.read_event().unwrap() { Event::Start(e) => { current_tag = e.name().as_ref().to_string_lossy().into_owned(); } Event::Text(e) => { let text = e.unescape().unwrap().into_owned(); match current_tag.as_str() { "Modulus" => modulus = text, "Exponent" => exponent = text, _ => (), } } Event::Eof => break, _ => (), } }
2. 将Base64字符串转换为BigUint
XML中的Modulus和Exponent是Base64编码的字节,需要先解码,再转换为BigUint:
use base64::decode; use rsa::BigUint; // 解码模数和指数的Base64字符串 let modulus_bytes = decode(&modulus).expect("Failed to decode modulus"); let exponent_bytes = decode(&exponent).expect("Failed to decode exponent"); // 转换为BigUint(大端字节序) let n = BigUint::from_bytes_be(&modulus_bytes); let e = BigUint::from_bytes_be(&exponent_bytes);
3. 创建RsaPublicKey实例并调用加密函数
用RsaPublicKey::new创建公钥,注意处理可能的无效公钥错误:
use rsa::RsaPublicKey; let pub_key = RsaPublicKey::new(n, e).expect("Invalid RSA public key"); // 调用加密函数 let encrypted_data = Crypto::encrypt(pub_key, b"hello");
完整修改后的get_key函数片段
pub async fn get_key() { // ... 省略前面的TCP通信和JSON解析代码 ... let xml = json_value["public_key"].as_str().unwrap(); // 修正后的XML解析 let mut reader = Reader::from_str(xml); reader.trim_text(true); let mut modulus = String::new(); let mut exponent = String::new(); let mut current_tag = String::new(); loop { match reader.read_event().unwrap() { Event::Start(e) => { current_tag = e.name().as_ref().to_string_lossy().into_owned(); } Event::Text(e) => { let text = e.unescape().unwrap().into_owned(); match current_tag.as_str() { "Modulus" => modulus = text, "Exponent" => exponent = text, _ => (), } } Event::Eof => break, _ => (), } } // 转换为BigUint let modulus_bytes = base64::decode(&modulus).expect("Failed to decode modulus"); let exponent_bytes = base64::decode(&exponent).expect("Failed to decode exponent"); let n = BigUint::from_bytes_be(&modulus_bytes); let e = BigUint::from_bytes_be(&exponent_bytes); // 创建公钥并加密 let pub_key = RsaPublicKey::new(n, e).expect("Invalid RSA public key"); let encrypted_data = Crypto::encrypt(pub_key, b"hello"); println!("Encrypted data: {:?}", encrypted_data); }
额外注意事项
- 确保在
Cargo.toml中添加base64依赖:base64 = "0.21" - 避免过度使用
unwrap(),实际项目中建议用Result进行错误处理,比如将get_key改为返回Result<(), Box<dyn Error>> - 确认服务器返回的XML公钥结构是否符合标准,如果结构不同,需要调整标签匹配逻辑
内容的提问来源于stack exchange,提问作者Saviam
相关产品推荐
相关产品推荐

