51 lines
1.8 KiB
Rust
51 lines
1.8 KiB
Rust
// [TSM.ID].[11031972] -- All Rights Reserved. Proprietary & Confidential.
|
|
use aes_gcm::{
|
|
aead::{Aead, AeadCore, KeyInit, OsRng},
|
|
Aes256Gcm, Nonce, Key
|
|
};
|
|
|
|
pub type ShieldResult<T> = std::result::Result<T, String>;
|
|
|
|
/// Mengamankan frame video dengan AES-256-GCM.
|
|
/// Frame ini tidak akan bisa dibuka oleh VPS XCU (Zero-Knowledge).
|
|
pub fn lock_video_frame(secret_key: &[u8], frame_data: &[u8]) -> ShieldResult<Vec<u8>> {
|
|
if secret_key.len() != 32 {
|
|
return Err("Kunci AES-256 wajib 32 bytes (256 bits).".to_string());
|
|
}
|
|
|
|
let key = Key::<Aes256Gcm>::from_slice(secret_key);
|
|
let cipher = Aes256Gcm::new(key);
|
|
|
|
// Generate Nonce Kuantum (12-bytes)
|
|
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
|
|
|
|
// Eksekusi Enkripsi Militer
|
|
let mut ciphertext = cipher.encrypt(&nonce, frame_data)
|
|
.map_err(|e| format!("Gagal mengenkripsi frame: {:?}", e))?;
|
|
|
|
// Menggabungkan Nonce dengan Ciphertext agar bisa di dekripsi di ujung penerima
|
|
let mut final_payload = nonce.to_vec();
|
|
final_payload.append(&mut ciphertext);
|
|
|
|
Ok(final_payload)
|
|
}
|
|
|
|
/// Membuka frame video yang datang dari Server Buta (XCU)
|
|
pub fn unlock_video_frame(secret_key: &[u8], encrypted_payload: &[u8]) -> ShieldResult<Vec<u8>> {
|
|
if encrypted_payload.len() < 12 {
|
|
return Err("Payload cacat atau telah diubah peretas (Missing Nonce).".to_string());
|
|
}
|
|
|
|
let key = Key::<Aes256Gcm>::from_slice(secret_key);
|
|
let cipher = Aes256Gcm::new(key);
|
|
|
|
let (nonce_bytes, ciphertext) = encrypted_payload.split_at(12);
|
|
let nonce = Nonce::from_slice(nonce_bytes);
|
|
|
|
// Eksekusi Dekripsi Militer
|
|
let plaintext = cipher.decrypt(nonce, ciphertext)
|
|
.map_err(|_| "Kunci salah atau Data disadap (Integrity Check Failed).".to_string())?;
|
|
|
|
Ok(plaintext)
|
|
}
|