Update text.rs
Added timing attack protection for encryption, was overlooked. This changed the type from &str to Option<String>.
This commit is contained in:
parent
ce9de3d651
commit
b1032918da
|
|
@ -1,6 +1,3 @@
|
||||||
use openssl::symm::{encrypt, Cipher};
|
|
||||||
use base64::encode;
|
|
||||||
use crate::encryption::text::hmac::calculate_hmac;
|
|
||||||
/// Encrypts the input text with an optional encryption key.
|
/// Encrypts the input text with an optional encryption key.
|
||||||
///
|
///
|
||||||
/// The `input` parameter is the text to be encrypted.
|
/// The `input` parameter is the text to be encrypted.
|
||||||
|
|
@ -18,7 +15,7 @@
|
||||||
/// let key = Some("your_secret_key");
|
/// let key = Some("your_secret_key");
|
||||||
/// let encrypted = encrypts(input, key);
|
/// let encrypted = encrypts(input, key);
|
||||||
///
|
///
|
||||||
/// assert!(encrypted.len() > 0);
|
/// assert!(encrypted.as_ref().unwrap().len() > 0);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Encrypt a text without providing a custom key:
|
/// Encrypt a text without providing a custom key:
|
||||||
|
|
@ -29,25 +26,40 @@
|
||||||
/// let input = "ThisIsJustaTestString";
|
/// let input = "ThisIsJustaTestString";
|
||||||
/// let encrypted = encrypts(input, None);
|
/// let encrypted = encrypts(input, None);
|
||||||
///
|
///
|
||||||
/// assert!(encrypted.len() > 0);
|
/// assert!(encrypted.as_ref().unwrap().len() > 0);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn encrypts(input: &str, key: Option<&str>) -> String {
|
use openssl::symm::{encrypt, Cipher};
|
||||||
|
use base64::encode;
|
||||||
|
use crate::encryption::text::hmac::calculate_hmac;
|
||||||
|
use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
|
pub fn encrypts(input: &str, key: Option<&str>) -> Option<String> {
|
||||||
let cipher = Cipher::aes_128_cbc();
|
let cipher = Cipher::aes_128_cbc();
|
||||||
let key = key.unwrap_or("welovenfts");
|
let key = key.unwrap_or("welovenfts");
|
||||||
let iv_bytes = &input.to_string()[..10];
|
let iv_bytes = &input.to_string()[..10];
|
||||||
let iv = base64::encode(iv_bytes);
|
let iv = base64::encode(iv_bytes);
|
||||||
let mut padded_key = key.as_bytes().to_vec();
|
let mut padded_key = key.as_bytes().to_vec();
|
||||||
while padded_key.len() < 16 {
|
while padded_key.len() < 16 {
|
||||||
padded_key.push(b'\0');
|
padded_key.push(b'\0');
|
||||||
}
|
}
|
||||||
let ciphertext = encrypt(cipher, &padded_key, Some(iv.as_bytes()), input.as_bytes()).unwrap();
|
let ciphertext = encrypt(cipher, &padded_key, Some(iv.as_bytes()), input.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
// Calculate HMAC
|
||||||
let hmac = calculate_hmac(&ciphertext, &padded_key);
|
let hmac = calculate_hmac(&ciphertext, &padded_key);
|
||||||
let mut result = iv.into_bytes();
|
|
||||||
result.extend_from_slice(&hmac);
|
// Constant-time compare HMAC to protect against timing attacks
|
||||||
result.extend_from_slice(&ciphertext);
|
if hmac.ct_eq(&calculate_hmac(&ciphertext, &padded_key)).unwrap_u8() == 1 {
|
||||||
let encoded_result = encode(&result);
|
let mut result = iv.into_bytes();
|
||||||
encoded_result
|
result.extend_from_slice(&hmac);
|
||||||
|
result.extend_from_slice(&ciphertext);
|
||||||
|
let encoded_result = encode(&result);
|
||||||
|
Some(encoded_result)
|
||||||
|
} else {
|
||||||
|
println!("Encryption HMAC validation failed");
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod hmac {
|
pub mod hmac {
|
||||||
pub(crate) fn calculate_hmac(data: &[u8], key: &[u8]) -> Vec<u8> {
|
pub(crate) fn calculate_hmac(data: &[u8], key: &[u8]) -> Vec<u8> {
|
||||||
use openssl::hash::MessageDigest;
|
use openssl::hash::MessageDigest;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue