Add salt to AES key

This commit is contained in:
Michael Mikovsky
2025-11-11 10:12:19 -07:00
parent 2b5074153b
commit 379b6a7e25
3 changed files with 55 additions and 97 deletions
-74
View File
@@ -1,82 +1,8 @@
use std::io::{Write, stdin, stdout};
use unshell_crypt::{
aes::{decrypt_aes, decrypt_aes_lines, encrypt_aes, encrypt_aes_lines},
base62::Base62,
fill, hash,
};
use unshell_lib::Announcement;
use unshell_obfuscate::format_obs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// let aaa = unshell_lib::crypt::aes::decrypt_aes(
// "611dcb046fcb11c3a0cf6d27ac7c8452e0120c2675d067a0dd857d9cd3d9df21140f1e2a715083a48180907eb90b87a6", //_1c82a871dda0f4372eb8e0dbba34c8de",
// "abc123abc",
// )?;
let key = "abc123abc";
println!(
"{}",
encrypt_aes_lines("Verylongstringthat1", &key, unshell_crypt::STATIC_IV)
);
println!(
"{}",
encrypt_aes_lines("Verylongstringthat12", &key, unshell_crypt::STATIC_IV)
);
println!(
"{}",
encrypt_aes_lines("Verylongstringthat123", &key, unshell_crypt::STATIC_IV)
);
println!(
"{}",
encrypt_aes_lines("Verylongstringthat1234", &key, unshell_crypt::STATIC_IV)
);
println!(
"{}",
encrypt_aes_lines("Verylongstringthat12345", &key, unshell_crypt::STATIC_IV)
);
// let e = Base62::encode_full(data, &key);
// let e = "_Nl8MlCFOyM4egPSXfo0wE4tfA0vOfBSZCx1TpKzjhI2qfahTrwh4JE1pJpcBttQqz_";
// let mut buf = [0u8; 256];
// _L1IuRLMW8tZN68RerKcbltQl675Yeq930NbcxsEfYYf_
// _L1IuRLMW8tZN68RerKcblyGtqOCLeLuBu3ormgklt3J_
// _L1IuRLMW8tZN68RerKcblKi37HPcZRonvwFUS5SZc0C_
// _L1IuRLMW8tZN68RerKcblya0Yw6TrFQxruqpemtv3K2_
// fill(&mut buf);
// for byte in buf.iter() {
// print!("{}, ", byte);
// }
// src/main.rs:13
// _SqF7lDRCyatsM4hnUTNAOq_
//
// _Nl8MlCFOyM4egPSXfo0wE4tfA0vOfBSZCx1TpKzjhI2qfahTrwh4JE1pJpcBttQqz_
// unshell-lib-0.0.0/src/module/manager.rs:52
// println!("Key: {}", String::from_utf8_lossy(&key));
// let encoded = Base62::decode_full(&e, &key).unwrap();
// let plaintext = decrypt_aes_lines(&data, &key, unshell_crypt::STATIC_IV);
// let base = Base62::new(&hash("TEST_KEY".as_bytes()), 0);
// let encoded = base.encode("123 1234 12342 1235e2".as_bytes());
// println!("Base62: {}", plaintext);
// let base = Base62::new(&hash("TEST_KEY".as_bytes()), 0);
// let decoded = base.decode(&encoded).unwrap();
// println!("Decoded: {}", String::from_utf8(decoded).unwrap());
// Ok(())
let mut serverruntime = unshell_lib::server::ListenerRuntime::new();
loop {
+51 -19
View File
@@ -9,45 +9,74 @@ fn pkcs7_padded_length(input_len: usize) -> usize {
}
pub fn encrypt_aes(plaintext: &str, key_str: &str, iv: [u8; 16]) -> String {
let plaintext = plaintext.as_bytes();
// Hash the env key to get a 32-byte (256-bit) AES key
let key = hash(key_str.as_bytes());
let plaintext = plaintext.as_bytes();
// Generate a psudo-random salt byte based on the plaintext
// I hope this does not break the encryption.
let mut salt = 0;
for byte in plaintext {
salt ^= byte;
}
let mut key_salted = key.clone();
// Salt the key by XORing the salt byte with all the key bytes.
// This ensures that the "hash" generated from the plaintext will
// make the encrypted result extremely different.
for i in 0..32 {
key_salted[i] ^= salt;
}
let buf_len = pkcs7_padded_length(plaintext.len());
let mut buf = vec![0u8; buf_len];
let pt_len = plaintext.len();
buf[..pt_len].copy_from_slice(&plaintext);
let ct = cbc::Encryptor::<aes::Aes256>::new(&key.into(), &iv.into())
.encrypt_padded_mut::<Pkcs7>(&mut buf, pt_len)
.unwrap();
Base62::encode_full(ct, &key)
let mut ct = cbc::Encryptor::<aes::Aes256>::new(&key_salted.into(), &iv.into())
.encrypt_padded_mut::<Pkcs7>(&mut buf, pt_len)
.unwrap()
.to_vec();
// Add the salt byte to the key byte,
ct.insert(0, salt);
// Encode result in base62
Base62::encode_full(&ct, &key)
}
pub fn encrypt_aes_lines(plaintext: &str, key_str: &str, iv: [u8; 16]) -> String {
format!("_{}_", encrypt_aes(plaintext, key_str, iv))
}
pub fn decrypt_aes(input: &str, key_str: &str, iv: [u8; 16]) -> String {
pub fn decrypt_aes(input: &str, key_str: &str, iv: [u8; 16]) -> Result<String, String> {
// Hash the env key to get a 32-byte (256-bit) AES key
let key = hash(key_str.as_bytes());
let mut key = hash(key_str.as_bytes());
let cipher_bytes = Base62::decode_full(input, &key).unwrap();
let mut cipher_bytes = Base62::decode_full(input, &key).unwrap();
let salt = cipher_bytes.remove(0);
// XOR the salt bytes with the key bytes
// This replicates
for i in 0..32 {
key[i] ^= salt;
}
// Create buffer for result
let buf_len = cipher_bytes.len();
let mut buf: Vec<u8> = vec![0; buf_len];
buf[..cipher_bytes.len()].copy_from_slice(&cipher_bytes);
if let Ok(pt) = cbc::Decryptor::<aes::Aes256>::new(&key.into(), &iv.into())
let pt = cbc::Decryptor::<aes::Aes256>::new(&key.into(), &iv.into())
.decrypt_padded_mut::<Pkcs7>(&mut buf)
{
String::from_utf8_lossy(pt).to_string()
} else {
"<decryption failed>".to_string()
}
.map_err(|_| "decryption failed".to_string())?;
Ok(String::from_utf8_lossy(pt).to_string())
}
pub fn decrypt_aes_lines(input: &str, key_str: &str, iv: [u8; 16]) -> String {
@@ -57,14 +86,17 @@ pub fn decrypt_aes_lines(input: &str, key_str: &str, iv: [u8; 16]) -> String {
for aes_block in Regex::new(r"_([0-9a-zA-Z]*?)_").unwrap().find_iter(&input) {
let range = aes_block.range();
let aes_block = aes_block.as_str()[1..(aes_block.len() - 1)].to_string();
let decrypted_block = decrypt_aes(&aes_block, key_str, iv);
let range = (range.start + total_offset as usize)..(range.end + total_offset as usize);
if let Ok(decrypted_block) = decrypt_aes(&aes_block, key_str, iv) {
let range = (range.start + total_offset as usize)..(range.end + total_offset as usize);
// Offset range by the difference between the decrypted block length and the original range length
total_offset += decrypted_block.len().clone() - (range.end - range.start);
// Offset range by the difference between the decrypted block length and the original range length
total_offset += decrypted_block.len().clone() - (range.end - range.start);
decrypted_result.replace_range(range, &decrypted_block);
decrypted_result.replace_range(range, &decrypted_block);
} else {
continue;
}
}
decrypted_result
+4 -4
View File
@@ -123,13 +123,15 @@ impl Base62 {
let base = Base62::new(&key, length % 255);
let encoded = base.encode(data);
// For the case that the encoded length is not equal to the predicted length
// The nonce must be derived from this length, so this needs to be ensured
//
// Re-encode with the correct length
if encoded.len() != length {
let len = encoded.len();
let base = Base62::new(&key, len % 255);
let encoded = base.encode(data);
println!("Fallback");
assert_eq!(encoded.len(), len);
encoded
@@ -141,8 +143,6 @@ impl Base62 {
let base = Base62::new(&key, data.len() % 255);
base.decode(data)
}
// pub fn encode_full
}
// Helper: Check if big integer (as bytes) is zero