Rust中用ring实现RSA公私钥加解密
1. 添加依赖
安装 rust 1.85,较新的版本语法有变化,不支持1.75部分已有代码
rustup install 1.85
rustup default 1.85
在Cargo.toml
中引入库:
[dependencies]
rsa = "0.9" # RSA专用库
rand = "0.8" # 随机数生成
sha2 = "0.10"
2. 生成RSA密钥对
以下是用rsa
库生成RSA密钥对的代码:
// 生成RSA密钥对(2048位)let mut rng = OsRng;let private_key = RsaPrivateKey::new(&mut rng, 2048)?;let public_key = RsaPublicKey::from(&private_key);
3. 公钥加密数据
使用公钥对明文加密(采用OAEP填充方案,更安全):
// OAEP加密(SHA256)let encrypted_oaep = public_key.encrypt(&mut rng, Oaep::new::<Sha256>(), data)?;println!("OAEP加密: {:?}", encrypted_oaep);
4. 私钥解密数据
使用私钥对密文解密:
// OAEP解密let decrypted_oaep = private_key.decrypt(Oaep::new::<Sha256>(), &encrypted_oaep)?;println!("OAEP解密: {}", String::from_utf8_lossy(&decrypted_oaep));
5. 完整示例代码
extern crate rand;
extern crate rsa;
extern crate sha2;use rsa::{RsaPrivateKey, RsaPublicKey, Pkcs1v15Encrypt, Oaep};
use rand::rngs::OsRng;
use sha2::Sha256;fn main() -> Result<(), Box<dyn std::error::Error>> {// 生成RSA密钥对(2048位)let mut rng = OsRng;let private_key = RsaPrivateKey::new(&mut rng, 2048)?;let public_key = RsaPublicKey::from(&private_key);// 原始数据let data = b"hello world";// PKCS1v15加密let encrypted_pkcs1 = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, data)?;println!("PKCS1v15加密: {:?}", encrypted_pkcs1);// PKCS1v15解密let decrypted_pkcs1 = private_key.decrypt(Pkcs1v15Encrypt, &encrypted_pkcs1)?;println!("PKCS1v15解密: {}", String::from_utf8_lossy(&decrypted_pkcs1));// OAEP加密(SHA256)let encrypted_oaep = public_key.encrypt(&mut rng, Oaep::new::<Sha256>(), data)?;println!("OAEP加密: {:?}", encrypted_oaep);// OAEP解密let decrypted_oaep = private_key.decrypt(Oaep::new::<Sha256>(), &encrypted_oaep)?;println!("OAEP解密: {}", String::from_utf8_lossy(&decrypted_oaep));Ok(())
}
输出示例:
PKCS1v15加密: [104, 40, 115, 63, 86, 217, 122, 33, 244, 188, 220, 171, 177, 161, 61, 133, 0, 93, 104, 197, 55, 233, 106, 81, 72, 44, 62, 44, 45, 223, 28, 13, 82, 32, 230, 164, 95, 36, 150, 247, 28, 122, 125, 207, 55, 36, 37, 185, 35, 191, 168, 250, 204, 84, 105, 225, 26, 241, 237, 184, 13, 65, 69, 159, 174, 99, 10, 39, 8, 70, 55, 244, 225, 102, 226, 142, 153, 116, 190, 91, 70, 47, 180, 210, 40, 53, 136, 149, 170, 34, 170, 248, 56, 78, 99, 75, 242, 250, 117, 104, 106, 174, 180, 248, 108, 220, 227, 173, 234, 68, 180, 250, 31, 232, 151, 199, 125, 182, 57, 25, 63, 123, 61, 152, 156, 38, 14, 55, 224, 170, 62, 213, 3, 148, 157, 6, 167, 199, 118, 240, 33, 118, 158, 210, 199, 101, 250, 164, 186, 39, 27, 123, 97, 246, 245, 185, 64, 69, 138, 3, 35, 2, 209, 167, 79, 30, 47, 41, 252, 27, 223, 17, 89, 111, 11, 90, 99, 249, 24, 244, 240, 228, 188, 18, 28, 176, 35, 4, 62, 88, 204, 24, 134, 54, 86, 229, 59, 54, 159, 190, 46, 40, 169, 151, 166, 244, 19, 171, 167, 246, 127, 10, 235, 15, 15, 6, 222, 33, 110, 172, 220, 208, 45, 207, 13, 136, 123, 254, 177, 120, 128, 231, 197, 199, 172, 134, 252, 137, 158, 58, 241, 78, 202, 187, 154, 244, 134, 41, 181, 147, 56, 193, 81, 2, 16, 77]
PKCS1v15解密: hello world
OAEP加密: [68, 236, 52, 141, 6, 255, 8, 1, 26, 94, 253, 154, 35, 140, 163, 169, 203, 69, 244, 172, 94, 84, 92, 180, 221, 17, 41, 170, 101, 167, 191, 128, 164, 66, 72, 223, 146, 255, 210, 63, 101, 58, 106, 147, 186, 3, 118, 198, 152, 114, 142, 238, 41, 134, 133, 135, 155, 113, 165, 177, 244, 118, 111, 202, 216, 252, 160, 56, 166, 15, 177, 207, 152, 192, 130, 151, 167, 51, 168, 243, 90, 26, 72, 26, 158, 36, 237, 190, 28, 159, 194, 6, 204, 64, 97, 79, 75, 182, 241, 124, 110, 160, 179, 84, 238, 117, 249, 7, 59, 120, 100, 13, 111, 244, 77, 30, 126, 21, 207, 155, 81, 139, 242, 183, 239, 9, 56, 59, 220, 208, 65, 180, 40, 236, 104, 154, 74, 186, 183, 112, 31, 125, 94, 54, 227, 142, 237, 224, 116, 208, 100, 133, 214, 121, 106, 162, 245, 153, 119, 35, 186, 38, 98, 99, 65, 68, 231, 48, 119, 47, 248, 102, 238, 31, 132, 182, 74, 92, 110, 165, 183, 245, 238, 122, 104, 82, 118, 140, 161, 193, 83, 35, 174, 114, 166, 240, 152, 211, 41, 61, 31, 131, 50, 134, 8, 17, 156, 212, 33, 45, 153, 151, 1, 74, 68, 171, 116, 177, 73, 118, 112, 37, 24, 249, 111, 123, 214, 79, 30, 190, 141, 205, 146, 82, 80, 243, 136, 78, 51, 128, 26, 149, 182, 170, 221, 209, 209, 199, 214, 94, 29, 64, 91, 195, 82, 173]
OAEP解密: hello world
有一些时间没有使用rust,以为用rust加解密是比较简单的功能,网上找篇文章按照示例操作就可以,但实际是会有坑。首先是rustup更新为最新版本,然后运行示例代码,结果报错,于是搜索解决方案,版本有更新需要增加语法,而且包的位置也有变化。然后要降级版本,看到1.75版本使用较多,然后安装1.75版本测试,报错
error: failed to download `base64ct v1.8.0`Caused by:unable to get packages from sourceCaused by:failed to parse manifest at `/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.8.0/Cargo.toml`Caused by:feature `edition2024` is requiredThe package requires the Cargo feature called `edition2024`, but that feature is not stabilized in this version of Cargo (1.80.1 (376290515 2024-07-16)).Consider trying a newer version of Cargo (this may require the nightly release).See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#edition-2024 for more information about the status of this feature.
然后是要升级版本,不确定哪个版本合适,于是升级到1.85试下。升级到1.85需要修改代码,增加extern语句,这在较低版本是不需要的,但是较新版本需要增加
extern crate rand;
extern crate rsa;
extern crate sha2;