1use crate::HexUtil;
2use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};
3use base64ct::LineEnding;
4use hmac::{Hmac, Mac};
5use rsa::{
6 pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey},
7 Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey,
8};
9use sha1::Sha1;
10use sha2::{Digest, Sha256};
11
12pub struct SecureUtil;
14
15impl SecureUtil {
16 pub fn aes_random_key() -> String {
18 "".to_string()
19 }
20
21 pub fn aes_encode(bytes: &[u8], key: &str) -> String {
23 "".to_string()
24 }
25
26 pub fn aes_decode(decode_str: &str, key: &str) -> Vec<u8> {
28 vec![]
29 }
30
31 pub fn rsa_random_key() -> (RsaPublicKey, RsaPrivateKey) {
42 let mut rng = rand::thread_rng(); let bits = 2048;
44 let priv_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
46 let pub_key = RsaPublicKey::from(&priv_key);
48 (pub_key, priv_key)
49 }
50
51 pub fn rsa_encode(pub_key: &RsaPublicKey, bytes: &[u8]) -> Vec<u8> {
66 let mut rng = rand::thread_rng(); let enc_data = pub_key
68 .encrypt(&mut rng, Pkcs1v15Encrypt, bytes)
69 .expect("failed to encrypt");
70 enc_data
71 }
72
73 pub fn rsa_decode(priv_key: &RsaPrivateKey, enc_data: &[u8]) -> Vec<u8> {
85 let dec_data = priv_key
87 .decrypt(Pkcs1v15Encrypt, &enc_data)
88 .expect("failed to decrypt");
89 dec_data
90 }
91
92 pub fn rsa_private_key_to_pkcs8(priv_key: &RsaPrivateKey) -> String {
106 let x = priv_key.to_pkcs8_pem(LineEnding::LF).unwrap();
107 x.to_string()
108 }
109
110 pub fn rsa_public_key_to_pkcs8(pub_key: &RsaPublicKey) -> String {
124 let x = pub_key.to_public_key_pem(LineEnding::LF).unwrap();
125 x
126 }
127
128 pub fn rsa_private_key_from_pkcs8(pkcs8_string: &str) -> RsaPrivateKey {
141 let res = RsaPrivateKey::from_pkcs8_pem(pkcs8_string).unwrap();
143 res
144 }
145 pub fn rsa_public_key_from_pkcs8(pkcs8_string: &str) -> RsaPublicKey {
158 let res = RsaPublicKey::from_public_key_pem(pkcs8_string).unwrap();
159 res
160 }
161
162 pub fn sha256_string(bytes: &[u8]) -> String {
172 let result = Sha256::digest(bytes);
174 let result = &result[..];
175 HexUtil::to_hex(result)
177 }
178
179 pub fn md5_string(bytes: &[u8]) -> String {
180 let data_md5 = md5::compute(bytes);
182 let md5_string = format!("{:x}", data_md5);
184 md5_string
185 }
186
187 pub fn base64_encode(bytes: &[u8]) -> String {
195 BASE64_STANDARD.encode(bytes)
196 }
197
198 pub fn base64_decode(base64_str: &str) -> Result<Vec<u8>, DecodeError> {
213 BASE64_STANDARD.decode(base64_str)
214 }
215
216 pub fn hmac_sha1(data: &[u8], key: &str) -> Vec<u8> {
230 let key = key.as_bytes();
231 let mut hmac = Hmac::<Sha1>::new_from_slice(key).expect("HMAC can take key of any size");
233 hmac.update(data);
235 let result = hmac.finalize();
237 let hmac_bytes = result.into_bytes();
238 hmac_bytes.to_vec()
239 }
240
241 #[deprecated(note = "This function is deprecated, please use md5_string instead")]
258 pub fn to_md5_str(bytes: &[u8]) -> String {
259 Self::md5_string(bytes)
260 }
261
262 pub fn to_md5(bytes: &[u8]) -> Vec<u8> {
276 let data_md5 = md5::compute(bytes).to_vec();
278 data_md5
279 }
280}
281
282#[cfg(test)]
283mod tests {
284
285 use super::*;
286
287 #[test]
288 fn test_base64() {
289 let bytes = "hello, rust!".as_bytes();
290 let base64_str = SecureUtil::base64_encode(bytes);
291 println!("{}", base64_str);
292 }
293
294 #[test]
295 fn test_sha256() {
296 let sha256_string = SecureUtil::sha256_string(b"hello world");
297 println!("{}", sha256_string);
298 assert_eq!(
299 sha256_string,
300 "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
301 );
302 }
303
304 #[test]
305 fn test_rsa() {
306 let (pub_key, priv_key) = SecureUtil::rsa_random_key();
307 let pub_pkcs8_string = SecureUtil::rsa_public_key_to_pkcs8(&pub_key);
318 let priv_pkcs8_string = SecureUtil::rsa_private_key_to_pkcs8(&priv_key);
319
320 println!("pub_pkcs8_string => {}", pub_pkcs8_string);
321 println!("priv_pkcs8_string => {}", priv_pkcs8_string);
322
323 let pub_key = SecureUtil::rsa_public_key_from_pkcs8(&pub_pkcs8_string);
324 let priv_key = SecureUtil::rsa_private_key_from_pkcs8(&priv_pkcs8_string);
325
326 let data = "hello world";
327 let enc_data = SecureUtil::rsa_encode(&pub_key, data.as_bytes());
328 let dec_data = SecureUtil::rsa_decode(&priv_key, &enc_data);
329 println!("解密后{}", std::str::from_utf8(&dec_data).unwrap())
330 }
331
332 #[test]
333 fn test_rsa2() {
334 let pub_pkcs8_string = r#"-----BEGIN PUBLIC KEY-----
336MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6HvM5v45WMgCVCM7gLyU
337q8Xi0fqwvfge7JU9C6niP+liQHyMALr9n+IQm76v/CnvfAYYnDJ1VYhLpGkPKJ2Q
33856InmEOSAcx9vfgGQcPkkTSqpH/vDHEgPysFsBAGVBvXfBxa9FBF8afrAmdqM3DO
339ygnWWCaSux0js2hkQB0+wUk3Lkw9yxcT+cK9D7aNaB3vVjxRVvGOuFVMuTFzLjis
340/1INfltSSvnCB4QPxA/h9YUrZ26itw7yQgGIiUbNydLx3X+qvWCGVOnYwX9z6wsF
3414Ch3VwlYF+H/y0zyjIuCpdJDy80D36lErcwmRpJhMciT4lXnLMTyZvlN0UFl492L
3421wIDAQAB
343-----END PUBLIC KEY-----"#;
344 let priv_pkcs8_string = r#"-----BEGIN PRIVATE KEY-----
345MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDoe8zm/jlYyAJU
346IzuAvJSrxeLR+rC9+B7slT0LqeI/6WJAfIwAuv2f4hCbvq/8Ke98BhicMnVViEuk
347aQ8onZDnoieYQ5IBzH29+AZBw+SRNKqkf+8McSA/KwWwEAZUG9d8HFr0UEXxp+sC
348Z2ozcM7KCdZYJpK7HSOzaGRAHT7BSTcuTD3LFxP5wr0Pto1oHe9WPFFW8Y64VUy5
349MXMuOKz/Ug1+W1JK+cIHhA/ED+H1hStnbqK3DvJCAYiJRs3J0vHdf6q9YIZU6djB
350f3PrCwXgKHdXCVgX4f/LTPKMi4Kl0kPLzQPfqUStzCZGkmExyJPiVecsxPJm+U3R
351QWXj3YvXAgMBAAECggEATgrBDgnpVlRN89Cf+OdVQRR8v+BX1G2mc+TlSTUOLkY6
352JUup89TRrwpEaQPqL8wkCI5DVKvbl4rZWaeq3weFzTwx7ntAWDo9O7g24XzRDa2Q
353WwhXRuXy3UGj9yZp+XIfNBqQrdMEp8qmqXftvrbvtAL5YT4Ro550jZVNkfg/SMKX
354VptR+ZGpjSWsQfLM+Q8i9GEo3FV1dpT41Uea96cfX2siaaNNhCUM3MYgVDRjp7gj
355N9qxHOil3ZmvJU2yRLBlwgtLO+5fQzGET/yOeoXJ9iCeyAz5MNweljdra4wNtriV
3569ECYR/d7R3Bz2DtaJ5ALyD80AeJ+1TTrLxa4exkHgQKBgQD7UXolf0J5qFMEn7yw
3570F7LNANX/Fx6T/ayf7MJEegHK0UYDc9wjyIQDcIdgauvqImseq7R5sQQbnAHdsZW
358f6bzb+1HjoUZr2c43QY4sBRDW7wfibtlgtaiMpIophlBwbvdcJRW65s7Ox8Czcl/
359JNqMdjXjHLSiEFND6v8Of68LFQKBgQDs0IByiZm7qJQaR8WOoXku5C0XLA5zCLyh
360jXTqla5m0qAFZU8abrvBl/o0+nhmGsMkQR0ssvLJLX/a0t1IWBq+WmIDB3YC4IVU
361eKoHY7AlDhMa0dJ+nbuvrPQdFsRAfH9CRhtMmQPCVsx41AXsQa/OKwUQJuNvhwMg
362AioMthWGOwKBgG6tvTtSRjZJuPXqWzELMxQOfgJ7s0ZyfNSzhGdUKXkuxykGu/p4
363LqofRQO1naSodqktBlyOYn5SBKhk2Igzg5TmD/tZeqiLJMxYGmtQsDvR5JGHGK5l
3645pxb5R5dt/XLmi61a76z2BNHwCp98mU6F72QOb8hXzOYOPNKRLVf6fjZAoGBAJD2
3652YpDvT3o5jBoOwEiy4Hu38NNjtLQSFhEtYtccVQ0HwzuhUvS+VB67gk8QjOOsmIh
366EfDo4kJQffHAHwFIHabkwRbFnHIKatPYwYygc5VbVkqWotorSFcz8oNUCnLHQ0eY
367juGG0YxHggd9EtsbIrl8EC9g/tyoszsG2CLL28U9AoGAbZsQM7989SiKtLJ652uw
3686kaRWItbBdVKPr5galsBhbe/eEEE6ePbJTeLroQ31u/jGZJNSyUjwfBq9k1OBfpL
369s7+EjYm9Yg5hcep499C2eRyqoX+2j8am2CYYy3rDPj8lYt+u/99oUyAyGYVKAByb
370j27x2gyifpYUwtDqYU5DwDU=
371-----END PRIVATE KEY-----"#;
372
373 println!("pub_pkcs8_string => {}", pub_pkcs8_string);
374 println!("priv_pkcs8_string => {}", priv_pkcs8_string);
375
376 let pub_key = SecureUtil::rsa_public_key_from_pkcs8(&pub_pkcs8_string);
377 let priv_key = SecureUtil::rsa_private_key_from_pkcs8(&priv_pkcs8_string);
378
379 let data = "hello world";
380 let enc_data = SecureUtil::rsa_encode(&pub_key, data.as_bytes());
381 let dec_data = SecureUtil::rsa_decode(&priv_key, &enc_data);
382 println!("解密后{}", std::str::from_utf8(&dec_data).unwrap())
383 }
384}