#[cfg(test)]
mod tests {
use crate::signer::{load_private_key, sign_with_rsa};
use base64::Engine;
use base64::engine::general_purpose::STANDARD as BASE64;
use rsa::RsaPrivateKey;
use rsa::pkcs1::{EncodeRsaPrivateKey, LineEnding};
use rsa::pkcs8::EncodePrivateKey;
fn generate_pkcs1_pem() -> (String, RsaPrivateKey) {
let mut rng = rand::thread_rng();
let private_key = RsaPrivateKey::new(&mut rng, 2048).expect("生成密钥失败");
let pem = private_key
.to_pkcs1_pem(LineEnding::LF)
.expect("编码 PKCS#1 PEM 失败");
(pem.to_string(), private_key)
}
fn generate_pkcs8_pem() -> (String, RsaPrivateKey) {
let mut rng = rand::thread_rng();
let private_key = RsaPrivateKey::new(&mut rng, 2048).expect("生成密钥失败");
let pem = private_key
.to_pkcs8_pem(LineEnding::LF)
.expect("编码 PKCS#8 PEM 失败");
(pem.to_string(), private_key)
}
fn generate_raw_base64() -> (String, RsaPrivateKey) {
let mut rng = rand::thread_rng();
let private_key = RsaPrivateKey::new(&mut rng, 2048).expect("生成密钥失败");
let der = private_key
.to_pkcs1_der()
.expect("编码 PKCS#1 DER 失败");
let raw_base64 = BASE64.encode(der.as_bytes());
(raw_base64, private_key)
}
#[test]
fn test_load_private_key_pkcs1() {
let (pem, _) = generate_pkcs1_pem();
let key = load_private_key(&pem).expect("加载 PKCS#1 私钥失败");
key.validate().expect("私钥验证失败");
}
#[test]
fn test_load_private_key_pkcs8() {
let (pem, _) = generate_pkcs8_pem();
let key = load_private_key(&pem).expect("加载 PKCS#8 私钥失败");
key.validate().expect("私钥验证失败");
}
#[test]
fn test_load_private_key_raw_base64() {
let (raw, _) = generate_raw_base64();
let key = load_private_key(&raw).expect("加载裸 Base64 私钥失败");
key.validate().expect("私钥验证失败");
}
#[test]
fn test_load_private_key_invalid() {
let result = load_private_key("invalid-key-data");
assert!(result.is_err(), "加载无效私钥应返回错误");
}
#[test]
fn test_load_private_key_empty() {
let result = load_private_key("");
assert!(result.is_err(), "加载空私钥应返回错误");
}
#[test]
fn test_sign_with_rsa_pkcs1() {
let (pem, private_key) = generate_pkcs1_pem();
let content = "tiger_id=test123×tamp=1234567890";
let signature = sign_with_rsa(&pem, content).expect("签名失败");
assert!(!signature.is_empty(), "签名结果不应为空");
let sig_bytes = BASE64.decode(&signature).expect("签名结果不是有效的 Base64");
use rsa::pkcs1v15::VerifyingKey;
use sha1::Sha1;
use signature::Verifier;
let public_key = private_key.to_public_key();
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
let sig = rsa::pkcs1v15::Signature::try_from(sig_bytes.as_slice()).expect("签名格式错误");
verifying_key
.verify(content.as_bytes(), &sig)
.expect("验签失败");
}
#[test]
fn test_sign_with_rsa_pkcs8() {
let (pem, private_key) = generate_pkcs8_pem();
let content = "biz_content={}&method=market_state";
let signature = sign_with_rsa(&pem, content).expect("签名失败");
assert!(!signature.is_empty(), "签名结果不应为空");
use rsa::pkcs1v15::VerifyingKey;
use sha1::Sha1;
use signature::Verifier;
let public_key = private_key.to_public_key();
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
let sig_bytes = BASE64.decode(&signature).expect("Base64 解码失败");
let sig = rsa::pkcs1v15::Signature::try_from(sig_bytes.as_slice()).expect("签名格式错误");
verifying_key
.verify(content.as_bytes(), &sig)
.expect("验签失败");
}
#[test]
fn test_sign_with_rsa_different_content_different_signature() {
let (pem, _) = generate_pkcs1_pem();
let sig1 = sign_with_rsa(&pem, "content1").expect("签名 content1 失败");
let sig2 = sign_with_rsa(&pem, "content2").expect("签名 content2 失败");
assert_ne!(sig1, sig2, "不同内容的签名不应相同");
}
#[test]
fn test_sign_with_rsa_invalid_key() {
let result = sign_with_rsa("invalid-key", "test content");
assert!(result.is_err(), "使用无效私钥签名应返回错误");
}
}
#[cfg(test)]
mod property_tests {
use crate::signer::sign_with_rsa;
use base64::Engine;
use base64::engine::general_purpose::STANDARD as BASE64;
use proptest::prelude::*;
use rsa::RsaPrivateKey;
use rsa::pkcs1::{EncodeRsaPrivateKey, LineEnding};
fn test_key_pair() -> (String, RsaPrivateKey) {
let mut rng = rand::thread_rng();
let private_key = RsaPrivateKey::new(&mut rng, 2048).expect("生成密钥失败");
let pem = private_key
.to_pkcs1_pem(LineEnding::LF)
.expect("编码 PEM 失败");
(pem.to_string(), private_key)
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(20))]
#[test]
fn rsa_sign_verify_roundtrip(content in ".{1,200}") {
let (pem, private_key) = test_key_pair();
let signature = sign_with_rsa(&pem, &content).expect("签名失败");
prop_assert!(!signature.is_empty(), "签名结果不应为空");
let sig_bytes = BASE64.decode(&signature).expect("签名结果不是有效的 Base64");
use rsa::pkcs1v15::VerifyingKey;
use sha1::Sha1;
use signature::Verifier;
let public_key = private_key.to_public_key();
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
let sig = rsa::pkcs1v15::Signature::try_from(sig_bytes.as_slice()).expect("签名格式错误");
verifying_key
.verify(content.as_bytes(), &sig)
.map_err(|e| TestCaseError::Fail(format!("验签失败: {}", e).into()))?;
}
}
}