mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-25 16:22:23 +01:00
Epg resource rewrite
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
use shared::error::{TuliproxError, TuliproxErrorKind};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use openssl::symm::{Cipher, Crypter, Mode};
|
||||
use rand::Rng;
|
||||
|
||||
use rand::{RngCore, rngs::OsRng, TryRngCore};
|
||||
use shared::error::{TuliproxError, TuliproxErrorKind};
|
||||
|
||||
fn encode_base64_string(input: &[u8]) -> String {
|
||||
general_purpose::URL_SAFE_NO_PAD.encode(input)
|
||||
@@ -32,45 +31,56 @@ pub fn deobfuscate_text(secret: &[u8], text: &str) -> Result<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encrypt_text(secret: &[u8; 16], text: &str) -> Result<String, TuliproxError> {
|
||||
let iv: [u8; 16] = rand::rng().random(); // Random IV (AES-CBC 16 Bytes)
|
||||
let cipher = Cipher::aes_128_cbc();
|
||||
let mut crypter = Crypter::new(cipher, Mode::Encrypt, secret, Some(&iv)).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
let mut ciphertext = vec![0; text.len() + cipher.block_size()];
|
||||
let mut count = crypter.update(text.as_bytes(), &mut ciphertext).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
count += crypter.finalize(&mut ciphertext[count..]).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
ciphertext.truncate(count);
|
||||
pub fn obscure_text(secret: &[u8;16], url: &str) -> Result<String, TuliproxError> {
|
||||
let mut iv = [0u8; 16];
|
||||
if OsRng.try_fill_bytes(&mut iv).is_err() {
|
||||
rand::rng().fill_bytes(&mut iv);
|
||||
}
|
||||
|
||||
// IV + Ciphertext
|
||||
let mut out = iv.to_vec();
|
||||
out.extend(ciphertext);
|
||||
// AES-CTR
|
||||
let cipher = Cipher::aes_128_ctr();
|
||||
let mut crypter = Crypter::new(cipher, Mode::Encrypt, secret, Some(&iv)).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't create cipher".to_string()))?;
|
||||
let mut buf = vec![0u8; url.len() + cipher.block_size()];
|
||||
let mut count = crypter.update(url.as_bytes(), &mut buf).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't update encryption".to_string()))?;
|
||||
count += crypter.finalize(&mut buf[count..]).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't finalize encryption".to_string()))?;
|
||||
buf.truncate(count);
|
||||
|
||||
// IV + Ciphertext → URL-safe Base64
|
||||
let mut out = Vec::with_capacity(iv.len() + buf.len());
|
||||
out.extend_from_slice(&iv);
|
||||
out.extend_from_slice(&buf);
|
||||
Ok(general_purpose::URL_SAFE_NO_PAD.encode(out))
|
||||
}
|
||||
|
||||
pub fn decrypt_text(secret: &[u8; 16], encrypted_text: &str) -> Result<String, TuliproxError> {
|
||||
let data = general_purpose::URL_SAFE_NO_PAD.decode(encrypted_text).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
let (iv, ciphertext) = data.split_at(16); // first 16 bytes IV
|
||||
let cipher = Cipher::aes_128_cbc();
|
||||
let mut crypter = Crypter::new(cipher, Mode::Decrypt, secret, Some(iv)).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
let mut decrypted = vec![0; ciphertext.len() + cipher.block_size()];
|
||||
let mut count = crypter.update(ciphertext, &mut decrypted).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
count += crypter.finalize(&mut decrypted[count..]).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))?;
|
||||
decrypted.truncate(count);
|
||||
|
||||
String::from_utf8(decrypted).map_err(|err| TuliproxError::new(TuliproxErrorKind::Info, err.to_string()))
|
||||
pub fn deobscure_text(secret: &[u8;16], encoded: &str) -> Result<String, TuliproxError> {
|
||||
// Base64 decode
|
||||
let data = general_purpose::URL_SAFE_NO_PAD.decode(encoded).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't decode base64".to_string()))?;
|
||||
|
||||
let (iv, ciphertext) = data.split_at(16);
|
||||
|
||||
// AES-CTR Decryption
|
||||
let cipher = Cipher::aes_128_ctr();
|
||||
let mut crypter = Crypter::new(cipher, Mode::Decrypt, secret, Some(iv)).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't create decrypt cipher".to_string()))?;
|
||||
let mut buf = vec![0u8; ciphertext.len() + cipher.block_size()];
|
||||
let mut count = crypter.update(ciphertext, &mut buf).map_err(|_errerr| TuliproxError::new(TuliproxErrorKind::Info, "Can't decrypt".to_string()))?;
|
||||
count += crypter.finalize(&mut buf[count..]).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't finalize decrypt".to_string()))?;
|
||||
buf.truncate(count);
|
||||
|
||||
String::from_utf8(buf).map_err(|_err| TuliproxError::new(TuliproxErrorKind::Info, "Can't create uf8 string from decrypted".to_string()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::crypto_utils::{decrypt_text, deobfuscate_text, encrypt_text, obfuscate_text};
|
||||
use rand::Rng;
|
||||
use crate::utils::crypto_utils::{obscure_text, deobscure_text, deobfuscate_text, obfuscate_text};
|
||||
use rand::{Rng};
|
||||
|
||||
#[test]
|
||||
fn test_encrypt() {
|
||||
fn test_obscure() {
|
||||
let secret: [u8; 16] = rand::rng().random(); // Random IV (AES-CBC 16 Bytes)
|
||||
let plain = "hello world";
|
||||
let encrypted = encrypt_text(&secret, plain);
|
||||
let decrypted = decrypt_text(&secret, &encrypted.unwrap()).unwrap();
|
||||
let encrypted = obscure_text(&secret, plain).unwrap();
|
||||
let decrypted = deobscure_text(&secret, &encrypted).unwrap();
|
||||
|
||||
assert_eq!(decrypted, plain);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user