From ad52c9c946cb31f8354c61cc5f1ab65c1806b0bf Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Mon, 11 Sep 2023 01:48:14 +0800 Subject: [PATCH] feat: update crypto rsa --- Cargo.toml | 2 +- src/crypto_rsa.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0dcdf28..4c9b163 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ openpgp-card-pcsc = "0.3.0" rand = "0.8.5" reqwest = { version = "0.11.14", features = ["blocking", "rustls", "rustls-tls"] } rpassword = "7.2.0" -rsa = "0.9.2" +rsa = { version = "0.9.2", features = ["pem"] } rust_util = "0.6.42" serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" diff --git a/src/crypto_rsa.rs b/src/crypto_rsa.rs index 89a056d..9131e0c 100644 --- a/src/crypto_rsa.rs +++ b/src/crypto_rsa.rs @@ -1,4 +1,6 @@ -use rsa::{BigUint, RsaPublicKey}; +use rsa::{BigUint, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; +use rsa::pkcs1::der::Decode; +use rsa::pkcs8::PrivateKeyInfo; use rsa::traits::PublicKeyParts; use rust_util::{opt_result, XResult}; use x509_parser::prelude::FromDer; @@ -28,13 +30,19 @@ fn normalize_public_key_pem(pem: &str) -> XResult> { if pem.ends_with("-----END PUBLIC KEY-----") { pem = pem.chars().take(pem.len() - "-----END PUBLIC KEY-----".len()).collect::(); } + if pem.starts_with("-----BEGIN PRIVATE KEY-----") { + pem = pem.chars().skip("-----BEGIN PRIVATE KEY-----".len()).collect::(); + } + if pem.ends_with("-----END PRIVATE KEY-----") { + pem = pem.chars().take(pem.len() - "-----END PRIVATE KEY-----".len()).collect::(); + } pem = pem.chars().filter(|c| *c != '\n' && *c != '\r').clone().collect::(); Ok(opt_result!(decode_base64(&pem), "Decode pem or der failed: {}")) } #[test] -fn t() { +fn test_parse_spki() { let public_key_pem = "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgK\ CAgEApUM8M+QRMUw0dIvXISFx\n43j4h9CK38Y9HD6kPcc3Z0dCGPiFy7Ze0OQebPWHyUZ2YmqsdyzFuOQuV9P2pxxj\n/W\ LIgRqZV8Jk8tWhtAjOOvm0MTc2rg+EJHfa+zhX4eFEMsj4DvQBMJDXiKnpXTM/\nj7oMKpIUQHqfXBwsEJHLmHZTLeEBEYK\ @@ -59,4 +67,54 @@ fn t() { 6146207a1f102fa753aa462148743fb36bd06cf8e46253c1619d856e7759f2268daf9be64c30caa5229323", public_key.n().to_str_radix(16)); assert_eq!("10001", public_key.e().to_str_radix(16)); +} + +#[test] +fn test_parse_spki_and_test() { + let private_key_pem = "-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsuTaS34xvrgr5 +ZXEuE8lYDYuLxATq1ds6/8YlNOeKReCGwRkObfKl0uyj79WLka2RCZELDiHyQcDG +OMJZLnLhU/PmQXkp7UR+a8HrRWBa2kiuGoF/IpBHlFM7bFLqYlcPe1lFDlYlYLN0 +fhkxmB9jKJBvsnkXi2fNypi0/kbJM5GANlfvUG30SV9flNjKSKAs6UIVN9vJrzpC +pDMw0lcXRZa1F0kj8gFX4AdUvoiQog2QYlX1cpkznYz2G4F8K5GwUfsgEUUTqqLC +d/lfnI2poKhCy5G2ejAYrOttV2Ke6R3XCPQuQG7Pag0wHeqxfKrtC07GIVO4qQw6 +hA1SIIQpAgMBAAECggEAH7SH3gIHB2ENRqZmVizvoqgp22gJ9wl2iqf0uVOyxOD6 +zAGaFdn81o+XPKiDrHD7SUpWQ48+j/ed6UT19+Tc1ZvRg4y1LwsMraAeIo/DlinH +eZ4H80xm65zAgoHp3nhavs7HnjN5gLb1egbDnSTtbgg+KyK5s6a1UUNFMMQUPk5Z +wdjOwJwPG6AYBqbHXsaCJHy4RBY3dI4RCM1d5QsFgmDvGoaIuFSrD2iCdnUlxbvj +62QvWuaW22hhIRZm6GQxHE0OqBbkzgJn/g8q8I57IzonET+k5wYzI8jRNRyHKR4z +fB71rYaeW36qHx/NjY2zLeEmva85r01F8/gcfIv9+QKBgQDZ0l78S4Q10S5j5IVI +tZsPjjfV2SlVKCzwspnYSPLyrgM0Fyg4F62Qm0J9Rm3mKSFNarCdcd7HcUqTRgUI +AjsG9rdTBISeUU6t98UcllfWtS0Q4u4y+Wa9nijnNiF3AirqgHWv+iPOX3fvgsC6 +wfkpCNMW8BTopaCwRnTWvCrhWwKBgQDK/0ohWDxqBkQ7DMUf29zUcJT5/FVw6KMn +EgLOnk8Z5qHmxy610qddB52gjLot0B+M4J3fLZtbkbyOUdOnrg1zbx6+TLdSAKRE +HT2sOxY+0D9y3tlziUyaJSQFnyX/PXbQa9iPDoZZURFdAulorqAMu2WzqzDn5HOK +s13P9X9DywKBgQCjviMtYc9nbXKEIVuYhvyjuvN6TJ9npqXx4zEHh/8qM2mxFN9l +G1ecZzqaVgFzjeO9AMD3+ovQPfgjsfVCSfr5hynUvIa9RL3yxVll3hb2DohsM0uB +Aj8bt/NjrCuH/Rcp5ZuSyGV2VAojAJXFTt/w2vNkQOJW6XtcR/q5GgbaFQKBgQCW +PQsoUp2j+q9U5MagJaDyucAIpHC39/WIXRQmx5PTn5YDrzcq6pVjjNdkk8LXVUmE +gllVa/Oned0LmBQF7hOWc49VWIH09vScVOfoKHL2WjobUkOt9tfy3bojTv5YQa1F +5AuLFTzprc4kAJuvFk7uHWPP7ctsVPAOn2G3IALosQKBgHzBvorOX4CeUn38mz3E +OjiPbL8hCS1DYx1ZteOds1JWwrA9ja745TPT4eMtuqduvQpz93HcjXly09KPN+i2 +Ogl/tEm7GQh6C9uXm3XbEnFGO/y9JQcef3eWWJTy4+mwKpq37SyWht65UYjE7adb +WrYun0ReUIgfONrtJaCxpgf/ +-----END PRIVATE KEY-----"; + let public_key_pem = "-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArLk2kt+Mb64K+WVxLhPJ +WA2Li8QE6tXbOv/GJTTnikXghsEZDm3ypdLso+/Vi5GtkQmRCw4h8kHAxjjCWS5y +4VPz5kF5Ke1EfmvB60VgWtpIrhqBfyKQR5RTO2xS6mJXD3tZRQ5WJWCzdH4ZMZgf +YyiQb7J5F4tnzcqYtP5GyTORgDZX71Bt9ElfX5TYykigLOlCFTfbya86QqQzMNJX +F0WWtRdJI/IBV+AHVL6IkKINkGJV9XKZM52M9huBfCuRsFH7IBFFE6qiwnf5X5yN +qaCoQsuRtnowGKzrbVdinukd1wj0LkBuz2oNMB3qsXyq7QtOxiFTuKkMOoQNUiCE +KQIDAQAB +-----END PUBLIC KEY-----"; + let public_key = parse_spki(public_key_pem).unwrap(); + let private_key_der = normalize_public_key_pem(&private_key_pem).unwrap(); + let private_key_info = PrivateKeyInfo::from_der(&private_key_der).unwrap(); + let private_key = RsaPrivateKey::try_from(private_key_info).unwrap(); + let mut rng = rand::thread_rng(); + let data = b"hello world"; + let enc_data = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, &data[..]).unwrap(); + let decrypted_data = private_key.decrypt(Pkcs1v15Encrypt, &enc_data).unwrap(); + assert_eq!(&data[..], &decrypted_data[..]); } \ No newline at end of file