Crate encrust

Source
Expand description

§encrust

Hide data at run-time by obfuscating it when it is not in use.

Encrust obfuscates the underlying data, and only exposes it when needed. When the deobfuscated data goes out of scope it is obfuscated until next time it is needed.

This crate also contains functionality to search for strings or byte patterns without including the strings / byte patterns themselves in the executable. The functionality requires the hashstrings feature to be enabled, which it is by default.

§Example usage

use encrust::{Encrustable, Encrusted};
use rand::RngCore;
use zeroize::Zeroize;

// Data types used with encrust must implement Zeroize to make sure data
// does not linger in memory after use.
#[derive(Encrustable, Zeroize)]
struct SecretData (String, u64, Vec<u8>);

let mut rng = rand::rng();

// This must be mut, otherwise it is not possible to call decrust.
let mut top_secret = Encrusted::new(
    SecretData ("A string".to_string(), 1337, vec![1,2,3,4,5,6]),
    rng.next_u64(),
);

{
    // Deobfuscate the data in top_secret to be able to read it.
    let mut deobfuscated = top_secret.decrust();
    assert_eq!("A string", deobfuscated.0);
    // It is possible to modify deobfuscated values as DerefMut is implemented.
    deobfuscated.1 += 1;
    assert_eq!(1338, deobfuscated.1);
    assert_eq!(&[1,2,3,4,5,6], deobfuscated.2.as_slice());
}
// deobfuscated is now out of scope and the data in top_secret is now obfuscated.

§Macros

Encrust contains several macros for embedding obfuscated values in executables. Obfuscation happens at compile-time, and the plain values are not included in the binary.

use encrust::{encrust, encrust_vec, encrust_file_bytes, encrust_file_string};

// When encrusting numbers, the data type must be specified.
let mut obfuscated_int = encrust!(1u32);
assert_eq!(*obfuscated_int.decrust(), 1u32);
let mut obfuscated_string = encrust!("Strings can also be encrusted.");
assert_eq!("Strings can also be encrusted.", obfuscated_string.decrust().as_str());
let mut obfuscated_array = encrust!([1u8,2u8,3u8]);
assert_eq!(&[1u8,2u8,3u8], obfuscated_array.decrust().as_slice());
let mut obfuscated_vec = encrust_vec![3i32,2i32,1i32];
assert_eq!(vec![3i32,2i32,1i32].as_slice(), obfuscated_vec.decrust().as_slice());

// Read Cargo.toml for this crate into a String.
let mut cargo_toml = encrust_file_string!("Cargo.toml");
// Read Cargo.toml for this crate into a byte array.
let mut cargo_toml_bytes = encrust_file_bytes!("Cargo.toml");
assert!(cargo_toml.decrust().as_bytes() == &cargo_toml_bytes.decrust()[..]);

§hashstrings macros

The hashstrings feature also contains macros to include the hash of strings and byte array without including the data itself.

use encrust::{hashstring, hashstring_ci, hashbytes};

let hashed_string = hashstring!("Case sensitive string, hashed");
assert!(hashed_string == "Case sensitive string, hashed");
assert!(hashed_string != "cAsE SeNSItIvE StRinG, HASHED");

let case_insensitive_hashed_string = hashstring_ci!("Case insensitive string, hashed");
assert!(case_insensitive_hashed_string == "Case insensitive string, hashed");
assert!(case_insensitive_hashed_string == "cASe INsenSItiVE StRiNg, hasHed");

let hashed_bytes = hashbytes!([0, 1, 2, 3, 4, 5]);
assert!(hashed_bytes == &[0, 1, 2, 3, 4, 5]);

§Limitations

Encrust currently only offers obfuscation of certain simple data structures, most container types are not supported yet. Additionally, certain data are not obfuscated at the moment. For vectors and strings, the actual data is obfuscated, but the pointer to the data as well as the length and capacity fields are not.

License: MIT

Macros§

encrustmacros
Encrust a literal value so the actual data is obfuscated before being included in the binary. Currently integers, strings and arrays of (arrays of) integers and strings are accepted.
encrust_file_bytesmacros
Read the contents of a file into a u8 array and encrust it so the actual file contents is obfuscated before being included in the binary.
encrust_file_stringmacros
Read the contents of a file into a String and encrust it so the actual file contents is obfuscated before being included in the binary.
encrust_vecmacros
Encrust a vec of literals. This works similarly to encrust! and supports the same data types, but puts the data in a vec.
hashbytesmacros and hashstrings
Hash an array of bytes so that the byte pattern can be searched for without including the bytes themselves in the executable.
hashstringmacros and hashstrings
Hash a string so that it can be searched for in the resulting executable without including the actual string. This macro creates a case sensitive encrust::Hashstring.
hashstring_cimacros and hashstrings
Similar to the hashstring! macro, but with a case insensitive encrust::Hashstring.

Structs§

Decrusted
Type used to access encrusted data. Use Encrusted::decrust to create Decrusted data.
Encrusted
Container struct for encrust, accepting Encrustable + Zeroize types for obfuscation and deobfuscation when needed.
Hashbyteshashstrings
The hash of a slice of u8’s. Can be used to search for data without storing the data itself in memory.
Hashstringhashstrings
The hash of a string. Can be used to search for strings without storing the string itself in memory.

Enums§

Sensitivityhashstrings
Used to specify whether a Hashstring should ignore case when comparing strings.

Traits§

Encrustable
Trait required to use data types with encrust. If it is avoidable, do not implement this manually, but use the derive macro to generate the implementation.

Derive Macros§

Encrustablemacros
Derive macro to allow custom structs and enums to be encrusted.