RSA 公私钥签名、验签基础

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(())
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容