You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:03:37