feat(rsa):基本完成RSA系列加密算法和签名算法的函数。
This commit is contained in:
parent
551209d4f1
commit
9a913b4bf4
|
@ -21,6 +21,8 @@ hmac-sha512 = "1.1.5"
|
||||||
image = "0.24.6"
|
image = "0.24.6"
|
||||||
md-5 = "0.10.5"
|
md-5 = "0.10.5"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
rsa = { version = "0.9.2", features = ["sha2"] }
|
||||||
sha1 = "0.10.5"
|
sha1 = "0.10.5"
|
||||||
|
sha2 = "0.10.7"
|
||||||
thiserror = "1.0.40"
|
thiserror = "1.0.40"
|
||||||
uuid = { version = "1.4.0", features = ["v4", "fast-rng"] }
|
uuid = { version = "1.4.0", features = ["v4", "fast-rng"] }
|
||||||
|
|
10
README.md
10
README.md
|
@ -16,10 +16,10 @@ Rust 中可以使用的常用辅助功能工具箱。主要配备以下功能:
|
||||||
- [x] No Padding
|
- [x] No Padding
|
||||||
- [x] ZerosPadding
|
- [x] ZerosPadding
|
||||||
- [x] Pkcs7Padding
|
- [x] Pkcs7Padding
|
||||||
- [ ] RSA 加解密算法
|
- [x] RSA 加解密算法
|
||||||
- [ ] 1024 位长
|
- [x] 1024 位长
|
||||||
- [ ] 2048 位长
|
- [x] 2048 位长
|
||||||
- [ ] KeyPair 生成器
|
- [x] KeyPair 生成器
|
||||||
- 散列算法。
|
- 散列算法。
|
||||||
- [x] Sha512 散列算法
|
- [x] Sha512 散列算法
|
||||||
- [x] Sha1 散列算法
|
- [x] Sha1 散列算法
|
||||||
|
@ -30,7 +30,7 @@ Rust 中可以使用的常用辅助功能工具箱。主要配备以下功能:
|
||||||
- [x] UUID 生成器
|
- [x] UUID 生成器
|
||||||
- [x] short UUID 生成器
|
- [x] short UUID 生成器
|
||||||
- 签名算法
|
- 签名算法
|
||||||
- [ ] RSA 签名算法
|
- [x] RSA 签名算法
|
||||||
- 验证码生成器
|
- 验证码生成器
|
||||||
- [x] 随机验证码生成算法
|
- [x] 随机验证码生成算法
|
||||||
- 序列化算法
|
- 序列化算法
|
||||||
|
|
|
@ -2,6 +2,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
pub mod aes;
|
pub mod aes;
|
||||||
pub mod des;
|
pub mod des;
|
||||||
|
pub mod rsa;
|
||||||
pub mod tdes;
|
pub mod tdes;
|
||||||
|
|
||||||
pub enum Padding {
|
pub enum Padding {
|
||||||
|
|
338
src/encryption/rsa.rs
Normal file
338
src/encryption/rsa.rs
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
use rsa::{
|
||||||
|
pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey, EncodeRsaPrivateKey, EncodeRsaPublicKey},
|
||||||
|
pkcs8::{DecodePrivateKey, DecodePublicKey},
|
||||||
|
signature::{Keypair, RandomizedSigner, SignatureEncoding, Verifier},
|
||||||
|
Pkcs1v15Encrypt,
|
||||||
|
};
|
||||||
|
use sha2::Sha256;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub enum RsaBitSize {
|
||||||
|
Bit1024,
|
||||||
|
Bit2048,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum RsaCryptionError {
|
||||||
|
#[error("Invalid public key")]
|
||||||
|
InvalidPublicKey,
|
||||||
|
#[error("Invalid private key")]
|
||||||
|
InvalidPrivateKey,
|
||||||
|
#[error("Unrecognized private key encoding or encrypted private key")]
|
||||||
|
UnrecognizedPrivateKeyEncoding,
|
||||||
|
#[error("Unrecognized public key encoding")]
|
||||||
|
UnrecognizedPublicKeyEncoding,
|
||||||
|
#[error("Private key required")]
|
||||||
|
PrivateKeyRequired,
|
||||||
|
#[error("Public key required")]
|
||||||
|
PublicKeyRequired,
|
||||||
|
#[error("Signing key required")]
|
||||||
|
SigningKeyRequired,
|
||||||
|
#[error("Verifying key required")]
|
||||||
|
VerifyingKeyRequired,
|
||||||
|
#[error("Failed to process data: {0}")]
|
||||||
|
CryptionFailed(#[from] rsa::errors::Error),
|
||||||
|
#[error("Unable to load signature")]
|
||||||
|
UnableToLoadSignature,
|
||||||
|
#[error("Signature verification failed")]
|
||||||
|
VerificationFailed,
|
||||||
|
#[error("Unable to export private key")]
|
||||||
|
UnableToExportPrivateKey,
|
||||||
|
#[error("Unable to export public key")]
|
||||||
|
UnableToExportPublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RsaCryptor {
|
||||||
|
private_key: Option<rsa::RsaPrivateKey>,
|
||||||
|
public_key: Option<rsa::RsaPublicKey>,
|
||||||
|
signing_key: Option<rsa::pkcs1v15::SigningKey<Sha256>>,
|
||||||
|
verifying_key: Option<rsa::pkcs1v15::VerifyingKey<Sha256>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_binary_private_key(key: &[u8]) -> Result<rsa::RsaPrivateKey, RsaCryptionError> {
|
||||||
|
let private_key = rsa::RsaPrivateKey::from_pkcs1_der(&key);
|
||||||
|
if let Ok(private_key) = private_key {
|
||||||
|
if private_key.validate().is_err() {
|
||||||
|
return Err(RsaCryptionError::InvalidPrivateKey);
|
||||||
|
}
|
||||||
|
return Ok(private_key);
|
||||||
|
}
|
||||||
|
let private_key = rsa::RsaPrivateKey::from_pkcs8_der(&key);
|
||||||
|
if let Ok(private_key) = private_key {
|
||||||
|
if private_key.validate().is_err() {
|
||||||
|
return Err(RsaCryptionError::InvalidPrivateKey);
|
||||||
|
}
|
||||||
|
return Ok(private_key);
|
||||||
|
}
|
||||||
|
Err(RsaCryptionError::UnrecognizedPrivateKeyEncoding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_text_private_key(pem: &str) -> Result<rsa::RsaPrivateKey, RsaCryptionError> {
|
||||||
|
let private_key = rsa::RsaPrivateKey::from_pkcs1_pem(pem);
|
||||||
|
if let Ok(private_key) = private_key {
|
||||||
|
if private_key.validate().is_err() {
|
||||||
|
return Err(RsaCryptionError::InvalidPrivateKey);
|
||||||
|
}
|
||||||
|
return Ok(private_key);
|
||||||
|
}
|
||||||
|
let private_key = rsa::RsaPrivateKey::from_pkcs8_pem(pem);
|
||||||
|
if let Ok(private_key) = private_key {
|
||||||
|
if private_key.validate().is_err() {
|
||||||
|
return Err(RsaCryptionError::InvalidPrivateKey);
|
||||||
|
}
|
||||||
|
return Ok(private_key);
|
||||||
|
}
|
||||||
|
Err(RsaCryptionError::UnrecognizedPrivateKeyEncoding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_binary_public_key(key: &[u8]) -> Result<rsa::RsaPublicKey, RsaCryptionError> {
|
||||||
|
let public_key = rsa::RsaPublicKey::from_pkcs1_der(&key);
|
||||||
|
if let Ok(public_key) = public_key {
|
||||||
|
return Ok(public_key);
|
||||||
|
}
|
||||||
|
let public_key = rsa::RsaPublicKey::from_public_key_der(&key);
|
||||||
|
if let Ok(public_key) = public_key {
|
||||||
|
return Ok(public_key);
|
||||||
|
}
|
||||||
|
Err(RsaCryptionError::UnrecognizedPublicKeyEncoding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_text_public_key(pem: &str) -> Result<rsa::RsaPublicKey, RsaCryptionError> {
|
||||||
|
let public_key = rsa::RsaPublicKey::from_pkcs1_pem(pem);
|
||||||
|
if let Ok(public_key) = public_key {
|
||||||
|
return Ok(public_key);
|
||||||
|
}
|
||||||
|
let public_key = rsa::RsaPublicKey::from_public_key_pem(pem);
|
||||||
|
if let Ok(public_key) = public_key {
|
||||||
|
return Ok(public_key);
|
||||||
|
}
|
||||||
|
Err(RsaCryptionError::UnrecognizedPublicKeyEncoding)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RsaCryptor {
|
||||||
|
/// 创建一个完全空白的 RSA 加密器。其中私钥、公钥、签名私钥和签名公钥都是空的,需要通过其他方法加载后方可使用。
|
||||||
|
pub fn new_empty() -> Self {
|
||||||
|
Self {
|
||||||
|
private_key: None,
|
||||||
|
public_key: None,
|
||||||
|
signing_key: None,
|
||||||
|
verifying_key: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 创建一个指定位数的 RSA 加密器,同时生成一套随机密钥。
|
||||||
|
/// 如果不能正常生成私钥,则直接返回错误。
|
||||||
|
///
|
||||||
|
/// - `bit_size`:密钥位数,目前支持 1024 位和 2048 位。
|
||||||
|
pub fn new(bit_size: RsaBitSize) -> Result<Self, RsaCryptionError> {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let bit_size = match bit_size {
|
||||||
|
RsaBitSize::Bit1024 => 1024,
|
||||||
|
RsaBitSize::Bit2048 => 2048,
|
||||||
|
};
|
||||||
|
let private_key = rsa::RsaPrivateKey::new(&mut rng, bit_size)
|
||||||
|
.map_err(|_| RsaCryptionError::InvalidPublicKey)?;
|
||||||
|
let public_key = rsa::RsaPublicKey::from(&private_key);
|
||||||
|
let signing_key = rsa::pkcs1v15::SigningKey::<Sha256>::new(private_key.clone());
|
||||||
|
let verify_key = signing_key.verifying_key();
|
||||||
|
Ok(Self {
|
||||||
|
private_key: Some(private_key),
|
||||||
|
public_key: Some(public_key),
|
||||||
|
signing_key: Some(signing_key),
|
||||||
|
verifying_key: Some(verify_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 从字节数组中加载私钥,如果加载失败,则返回错误。
|
||||||
|
/// 私钥加载成功后,公钥、签名私钥和签名公钥也会被同时自动生成。
|
||||||
|
///
|
||||||
|
/// - `key`:私钥内容。
|
||||||
|
pub fn load_binary_private_key<T: AsRef<[u8]>>(
|
||||||
|
&mut self,
|
||||||
|
key: T,
|
||||||
|
) -> Result<(), RsaCryptionError> {
|
||||||
|
let private_key = load_binary_private_key(key.as_ref())?;
|
||||||
|
let public_key = rsa::RsaPublicKey::from(&private_key);
|
||||||
|
let signing_key = rsa::pkcs1v15::SigningKey::<Sha256>::new(private_key.clone());
|
||||||
|
let verify_key = signing_key.verifying_key();
|
||||||
|
self.private_key = Some(private_key);
|
||||||
|
self.public_key = Some(public_key);
|
||||||
|
self.signing_key = Some(signing_key);
|
||||||
|
self.verifying_key = Some(verify_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 从文本中加载私钥,如果加载失败,则返回错误。
|
||||||
|
/// 私钥加载成功后,公钥、签名私钥和签名公钥也会被同时自动生成。
|
||||||
|
///
|
||||||
|
/// - `pem`:私钥内容。
|
||||||
|
pub fn load_text_private_key(&mut self, pem: &str) -> Result<(), RsaCryptionError> {
|
||||||
|
let private_key = load_text_private_key(pem)?;
|
||||||
|
let public_key = rsa::RsaPublicKey::from(&private_key);
|
||||||
|
let signing_key = rsa::pkcs1v15::SigningKey::<Sha256>::new(private_key.clone());
|
||||||
|
let verify_key = signing_key.verifying_key();
|
||||||
|
self.private_key = Some(private_key);
|
||||||
|
self.public_key = Some(public_key);
|
||||||
|
self.signing_key = Some(signing_key);
|
||||||
|
self.verifying_key = Some(verify_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 从字节数组中加载公钥,如果加载失败,则返回错误。
|
||||||
|
/// 公钥加载成功后,签名公钥也会被同时自动生成。私钥与签名私钥会被置为`None`。
|
||||||
|
/// ! 没有私钥的情况下,无法对内容进行解密。
|
||||||
|
///
|
||||||
|
/// - `key`:公钥内容。
|
||||||
|
pub fn load_binary_public_key<T: AsRef<[u8]>>(
|
||||||
|
&mut self,
|
||||||
|
key: T,
|
||||||
|
) -> Result<(), RsaCryptionError> {
|
||||||
|
let public_key = load_binary_public_key(key.as_ref())?;
|
||||||
|
let verify_key = rsa::pkcs1v15::VerifyingKey::<Sha256>::from(public_key.clone());
|
||||||
|
self.private_key = None;
|
||||||
|
self.public_key = Some(public_key);
|
||||||
|
self.signing_key = None;
|
||||||
|
self.verifying_key = Some(verify_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 从文本中加载公钥,如果加载失败,则返回错误。
|
||||||
|
/// 公钥加载成功后,签名公钥也会被同时自动生成。私钥与签名私钥会被置为`None`。
|
||||||
|
/// ! 没有私钥的情况下,无法对内容进行解密。
|
||||||
|
///
|
||||||
|
/// - `pem`:公钥内容。
|
||||||
|
pub fn load_text_public_key(&mut self, pem: &str) -> Result<(), RsaCryptionError> {
|
||||||
|
let public_key = load_text_public_key(pem)?;
|
||||||
|
let verify_key = rsa::pkcs1v15::VerifyingKey::<Sha256>::from(public_key.clone());
|
||||||
|
self.private_key = None;
|
||||||
|
self.public_key = Some(public_key);
|
||||||
|
self.signing_key = None;
|
||||||
|
self.verifying_key = Some(verify_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对指定内容进行加密,返回加密后的内容。
|
||||||
|
///
|
||||||
|
/// - `data`:待加密的内容。
|
||||||
|
pub fn encrypt<T: AsRef<[u8]>>(&self, data: T) -> Result<Vec<u8>, RsaCryptionError> {
|
||||||
|
if self.public_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PublicKeyRequired);
|
||||||
|
}
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let encrypted_data = self
|
||||||
|
.public_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.encrypt(&mut rng, Pkcs1v15Encrypt, data.as_ref())
|
||||||
|
.map_err(|e| RsaCryptionError::CryptionFailed(e))?;
|
||||||
|
Ok(encrypted_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对指定内容进行解密,返回解密后的内容。如果没有私钥,则返回错误。
|
||||||
|
///
|
||||||
|
/// - `data`:待解密的内容。
|
||||||
|
pub fn decrypt<T: AsRef<[u8]>>(&self, data: T) -> Result<Vec<u8>, RsaCryptionError> {
|
||||||
|
if self.private_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PrivateKeyRequired);
|
||||||
|
}
|
||||||
|
let decrypted_data = self
|
||||||
|
.private_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.decrypt(Pkcs1v15Encrypt, data.as_ref())
|
||||||
|
.map_err(|e| RsaCryptionError::CryptionFailed(e))?;
|
||||||
|
Ok(decrypted_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对指定内容进行签名,返回签名后的内容。如果没有签名私钥,则返回错误。
|
||||||
|
///
|
||||||
|
/// - `data`:待签名的内容。
|
||||||
|
pub fn sign<T: AsRef<[u8]>>(&self, data: T) -> Result<Vec<u8>, RsaCryptionError> {
|
||||||
|
if self.signing_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::SigningKeyRequired);
|
||||||
|
}
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let sign_data = self
|
||||||
|
.signing_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.sign_with_rng(&mut rng, data.as_ref())
|
||||||
|
.to_vec();
|
||||||
|
Ok(sign_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 对指定内容和签名进行验证,如果验证失败,则返回错误。
|
||||||
|
///
|
||||||
|
/// - `signature`:签名内容。
|
||||||
|
/// - `data`:待验证的内容。
|
||||||
|
pub fn verify<T: AsRef<[u8]>>(&self, signature: T, data: T) -> Result<(), RsaCryptionError> {
|
||||||
|
if self.verifying_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::VerifyingKeyRequired);
|
||||||
|
}
|
||||||
|
let signature = rsa::pkcs1v15::Signature::try_from(signature.as_ref())
|
||||||
|
.map_err(|_| RsaCryptionError::UnableToLoadSignature)?;
|
||||||
|
self.verifying_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.verify(data.as_ref(), &signature)
|
||||||
|
.map_err(|_| RsaCryptionError::VerificationFailed)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 以字节数组方式导出私钥,如果没有私钥,则返回错误。
|
||||||
|
pub fn export_private_key_binary(&self) -> Result<Vec<u8>, RsaCryptionError> {
|
||||||
|
if self.private_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PrivateKeyRequired);
|
||||||
|
}
|
||||||
|
let doc = self
|
||||||
|
.private_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.to_pkcs1_der()
|
||||||
|
.map_err(|_| RsaCryptionError::UnableToExportPrivateKey)?;
|
||||||
|
Ok(doc.as_bytes().to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 以PEM文本方式导出私钥,如果没有私钥,则返回错误。
|
||||||
|
pub fn export_private_key_pem(&self) -> Result<String, RsaCryptionError> {
|
||||||
|
if self.private_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PrivateKeyRequired);
|
||||||
|
}
|
||||||
|
let doc = self
|
||||||
|
.private_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.to_pkcs1_pem(rsa::pkcs1::LineEnding::CRLF)
|
||||||
|
.map_err(|_| RsaCryptionError::UnableToExportPrivateKey)?;
|
||||||
|
Ok(doc.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 以字节数组的方式导出公钥,如果没有公钥,则返回错误。
|
||||||
|
pub fn export_public_key_binary(&self) -> Result<Vec<u8>, RsaCryptionError> {
|
||||||
|
if self.public_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PublicKeyRequired);
|
||||||
|
}
|
||||||
|
let doc = self
|
||||||
|
.public_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.to_pkcs1_der()
|
||||||
|
.map_err(|_| RsaCryptionError::UnableToExportPublicKey)?;
|
||||||
|
Ok(doc.into_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 以PEM文本方式导出公钥,如果没有公钥,则返回错误。
|
||||||
|
pub fn export_public_key_pem(&self) -> Result<String, RsaCryptionError> {
|
||||||
|
if self.public_key.is_none() {
|
||||||
|
return Err(RsaCryptionError::PublicKeyRequired);
|
||||||
|
}
|
||||||
|
let doc = self
|
||||||
|
.public_key
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.to_pkcs1_pem(rsa::pkcs1::LineEnding::CRLF)
|
||||||
|
.map_err(|_| RsaCryptionError::UnableToExportPublicKey)?;
|
||||||
|
Ok(doc)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user