RSA 通常的用法是 公钥加密,私钥解密,这种方式适用于数据保密性场景。而 私钥加密,公钥解密 是非对称加密的一种反向操作,通常用于 数字签名 场景。它的目的不是保护数据隐私,而是验证数据的完整性和来源。
简言之: 公钥加密,私钥解密; 私钥签名,公钥验证。
1.前提:
1、服务器持有私钥,客户端使用证书(公钥)进行验证。
2、生成自签名证书和私钥,可用下列指令进行配对校验:
# 这两个md5如果一致,则说明两个文件匹配
openssl rsa -noout -modulus -in certificate.key| openssl md5
openssl x509 -noout -modulus -in certificate.crt| openssl md5
3、关于填充:
image.png
2.具体过程:
rsa = { version = "0.9.6", features = ["pem", "sha2"] }
x509-parser = "0.16.0"
sha2 = "0.10.8"
rand = "0.8.5"
use std::fs;
use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey};
use rsa::Pkcs1v15Sign;
use rsa::{RsaPrivateKey, RsaPublicKey};
use sha2::{Digest, Sha256};
use x509_parser::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 读取包含 RSA 私钥的 PEM 文件
let private_key_pem = fs::read_to_string("src/rsa/certificate.key").expect("1");
let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key_pem).unwrap();
println!("RSA 私钥成功加载!");
// 读取 X.509 证书文件
let cert_pem = fs::read_to_string("src/rsa/certificate.crt").expect("2");
let (_, pem) = parse_x509_pem(cert_pem.as_bytes()).expect("3");
let (_, cert) = X509Certificate::from_der(&pem.contents).expect("4");
// 提取公钥信息
let public_key_der = cert.public_key().raw.to_owned();
let public_key = RsaPublicKey::from_public_key_der(&public_key_der).expect("5");
println!("公钥成功加载!");
// 要加密的数据
let message = b"Hello, RSA Encryption!";
println!("原始数据: {:?}", String::from_utf8_lossy(message));
let mut hasher = Sha256::new();
hasher.update(message);
let msg_hash = hasher.finalize();
println!("原始消息哈希: {:?}", msg_hash);
// 使用私钥签名
let padding = Pkcs1v15Sign::new::<Sha256>();
let sig_data = private_key.sign(padding, &msg_hash).expect("6");
println!("签名数据: {:?}", sig_data);
// 使用公钥验证
let padding2 = Pkcs1v15Sign::new::<Sha256>();
match public_key.verify(padding2, &msg_hash, &sig_data) {
Ok(_) => println!("签名验证成功"),
Err(e) => {
println!("签名验证失败: {:?}", e.to_string())
}
}
Ok(())
}