Add files via upload

This commit is contained in:
viraladmin 2023-10-23 22:54:02 -06:00 committed by GitHub
parent 211d50b36c
commit 32e3d100fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 733 additions and 93 deletions

View File

@ -1,9 +1,10 @@
[package] [package]
name = "encrypted_images" name = "encrypted_images"
version = "1.2.0" version = "1.3.0"
edition = "2021" edition = "2021"
description = "Encrypt Text to Images and decrypt text from images." description = "Encrypt Text to Images and decrypt text from images."
authors = ["Bruce Bates | https://encryptedimages.art"] authors = ["Bruce Bates | https://encryptedimages.art"]
license = "MIT"
[dependencies] [dependencies]
openssl = { version = "0.10.57", features = ["vendored"] } openssl = { version = "0.10.57", features = ["vendored"] }
@ -15,3 +16,4 @@ sha2 = "0.10.7"
hex-literal = "0.4.1" hex-literal = "0.4.1"
encoding = "0.2" encoding = "0.2"
subtle = "2.4" subtle = "2.4"
rand = "0.8.5"

7
SUPPORT Normal file
View File

@ -0,0 +1,7 @@
Support this developers open source efforts:
bitcoin: bc1pf0s98gva7la6r9srepywwr4llqea8t0r4fj8qkdqqac0f9y5624sxpsmqq
ethereum: 0x78046716a783B94240ff6b4Ba6580F6D5690423A
cardano: addr1q8dxlqu824ghzn3extm8zjqzmr2u5fy4p0jpaqs6w8jpt4wkpgtm6wkc0me3gmgfgdadnpzdcj24yz3znme5w7kvm8vs0thea2
solana: HG1fpdqHkxSUyT85V6LGu8dbC3BK4JixiivjYLHVsazQ
tezos: tz2TL7ke3xyxWi4JbS6egscmpEP9Z9XrV86y

View File

@ -0,0 +1,15 @@
use encrypted_images::encryption::images::create_img;
fn main() {
let ciphertext = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
let style = "h";
let watermark = "bitcoin";
let r = Some(100);
let g = Some(134);
let b = Some(137);
if let Some(encoded_image) = create_img(ciphertext, style, watermark, r, g, b, None, None, None) {
println!("Encoded image: {}", encoded_image);
} else {
println!("Image creation or encoding failed.");
}
}

View File

@ -0,0 +1,15 @@
use encrypted_images::encryption::images::create_img;
fn main() {
let ciphertext = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
let style = "h";
let watermark = "bitcoin";
let r = Some(46);
let g = Some(115);
let b = Some(82);
if let Some(encoded_image) = create_img(ciphertext, style, watermark, r, g, b, None, None, None) {
println!("Encoded image: {}", encoded_image);
} else {
println!("Image creation or encoding failed.");
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
use encrypted_images::encryption::images::create_img;
fn main() {
let ciphertext = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
let style = "h2";
let watermark = "bitcoin";
let r = Some(100);
let g = Some(134);
let b = Some(137);
if let Some(encoded_image) = create_img(ciphertext, style, watermark, r, g, b, None, None, None) {
println!("Encoded image: {}", encoded_image);
} else {
println!("Image creation or encoding failed.");
}
}

11
examples/decode_image.rs Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
use encrypted_images::decryption::text::decrypts;
fn main() {
let encrypted_text = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
if let Some(decrypted_text) = decrypts(encrypted_text, None) {
println!("Decrypted text: {}", decrypted_text);
} else {
println!("Decryption failed.");
}
}

View File

@ -0,0 +1,11 @@
use encrypted_images::decryption::text::decrypts;
fn main() {
let encrypted_text = "OWFNTGpvaGFMbWtTUkE9PcjB/klKI3ix+Z0uVuYbd3zRqaTjMgxotQu4hz1FRSfPWRQMOBhLSI6+KFPl8qldeCPoUYvezvVMOScWll9OzCA=";
let key = Some("16characterslong");
if let Some(decrypted_text) = decrypts(encrypted_text, key) {
println!("Decrypted text: {}", decrypted_text);
} else {
println!("Decryption failed.");
}
}

View File

@ -0,0 +1,16 @@
use encrypted_images::encryption::text::encrypts;
use encrypted_images::encryption::images::create_img;
fn main() {
let key = Some("your_secret_key");
let ciphertext = "This is a secret message.";
let style = "h";
let encrypted = encrypts(ciphertext, key.clone(), None).unwrap();
let watermark = "bitcoin";
let image_data = create_img(&encrypted, style, watermark, None, None, None, None, None, None);
match image_data {
Some(encoded_image) => println!("Encoded Image:\n{}", encoded_image),
None => println!("Failed to create the image."),
}
}

View File

@ -0,0 +1,7 @@
use encrypted_images::encryption::text::encrypts;
fn main() {
let plaintext = "This Is Plain Text";
let encrypted_text = encrypts(plaintext, None, None).unwrap();
println!("Encrypted text: {}", encrypted_text);
}

View File

@ -0,0 +1,9 @@
use encrypted_images::encryption::text::encrypts;
fn main() {
let plaintext = "This Is Plain Text";
let key = Some("16characterslong");
let strength = Some("advanced");
let encrypted_text = encrypts(plaintext, key, strength).unwrap();
println!("Encrypted text: {}", encrypted_text);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,11 @@
/// This function takes an encoded result and an optional decryption key, and attempts to decrypt /// This function takes an encoded result and an optional decryption key, and attempts to decrypt
/// the result using AES-128 CBC decryption. It also verifies the integrity of the data using HMAC. /// the result using AES-128 CBC decryption. It also verifies the integrity of the data using HMAC.
/// ///
/// Timing Attack Protection:
/// The decryption process is designed to protect against timing attacks, ensuring secure
/// operation. It is suitable for standard encryption needs. Please see notes inside the encrypts
/// function to understand additional security. Default encryption settings are not maximum security.
///
/// # Arguments /// # Arguments
/// ///
/// * `encoded_result` - The Base64-encoded result to be decrypted. /// * `encoded_result` - The Base64-encoded result to be decrypted.
@ -25,15 +30,17 @@
/// ``` /// ```
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
use openssl::symm::{decrypt, Cipher}; use openssl::symm::{decrypt, Cipher};
use base64::decode;
use crate::encryption::text::hmac::calculate_hmac; use crate::encryption::text::hmac::calculate_hmac;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};
const CUSTOM_ENGINE: engine::GeneralPurpose =
engine::GeneralPurpose::new(&alphabet::STANDARD, general_purpose::PAD);
pub fn decrypts(encoded_result: &str, key: Option<&str>) -> Option<String> { pub fn decrypts(encoded_result: &str, key: Option<&str>) -> Option<String> {
let key = key.unwrap_or("welovenfts"); let key = key.unwrap_or("welovenfts");
let mut padded_key = key.as_bytes().to_vec(); let mut padded_key = key.as_bytes().to_vec();
while padded_key.len() < 16 { while padded_key.len() < 16 {
padded_key.push(b'\0'); padded_key.push(b'\0');
} }
let result_bytes = decode(encoded_result).ok()?; let result_bytes = CUSTOM_ENGINE.decode(encoded_result).ok()?;
let iv = &result_bytes[..16]; let iv = &result_bytes[..16];
let hmac = &result_bytes[16..48]; let hmac = &result_bytes[16..48];
let ciphertext = &result_bytes[48..]; let ciphertext = &result_bytes[48..];

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,25 @@
/// Encrypts the input text with an optional encryption key. /// Encrypts the input text with an optional encryption key with timing attack protections and
/// standard encryption security measures (which are optional).
/// ///
/// The `input` parameter is the text to be encrypted. /// The `input` parameter is the text to be encrypted.
/// ///
/// The `key` parameter is an optional encryption key. If not provided, a default key is used. /// The `key` parameter is an optional encryption key. If not provided, a default key is used.
/// ///
/// The `strength` parameter is optional security level. Is set this value can be default or
/// advanced.
///
/// # Notes
///
/// - This function has been updated to include timing attack protections to enhance security.
/// - The function uses static IV (Initialization Vector) bytes by default to generate consistant
/// encrypted text output. While suitable for some situations ensure to use the advanced
/// strength for highly sensative data but note that everytime you encrypt with the advanced
/// method the output will look differnt.
/// - Again stressing that the default security option is not the ideal choice for scenarios requiring the
/// highest level of encryption security.
/// - Without advanced security there are potentials for comparison attacks that can occur this encryption.
/// - Only use standard settings for novelty usage.
///
/// # Examples /// # Examples
/// ///
/// Encrypt a text with a custom key: /// Encrypt a text with a custom key:
@ -12,8 +28,8 @@
/// use encrypted_images::encryption::text::encrypts; /// use encrypted_images::encryption::text::encrypts;
/// ///
/// let input = "ThisIsJustaTestString"; /// let input = "ThisIsJustaTestString";
/// let key = Some("your_secret_key"); /// let key = "your_secret_key";
/// let encrypted = encrypts(input, key); /// let encrypted = encrypts(input, Some(key), None);
/// ///
/// assert!(encrypted.as_ref().unwrap().len() > 0); /// assert!(encrypted.as_ref().unwrap().len() > 0);
/// ``` /// ```
@ -24,42 +40,63 @@
/// use encrypted_images::encryption::text::encrypts; /// use encrypted_images::encryption::text::encrypts;
/// ///
/// let input = "ThisIsJustaTestString"; /// let input = "ThisIsJustaTestString";
/// let encrypted = encrypts(input, None); /// let encrypted = encrypts(input, None, None);
/// ///
/// assert!(encrypted.as_ref().unwrap().len() > 0); /// assert!(encrypted.as_ref().unwrap().len() > 0);
/// ``` /// ```
///
/// Encrypt a text with advanced security:
///
/// ```
/// use encrypted_images::encryption::text::encrypts;
///
/// let input = "ThisIsJustaTestString";
/// let strength = "advanced";
/// let encrypted = encrypts(input, None, Some(strength));
///
/// assert!(encrypted.as_ref().unwrap().len() > 0);
/// ```
use rand::{Rng};
use rand::rngs::OsRng;
use openssl::symm::{encrypt, Cipher}; use openssl::symm::{encrypt, Cipher};
use base64::encode;
use crate::encryption::text::hmac::calculate_hmac; use crate::encryption::text::hmac::calculate_hmac;
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};
const CUSTOM_ENGINE: engine::GeneralPurpose =
engine::GeneralPurpose::new(&alphabet::STANDARD, general_purpose::PAD);
pub fn encrypts(input: &str, key: Option<&str>) -> Option<String> {
pub fn encrypts(input: &str, key: Option<&str>, strength: Option<&str>) -> Option<String> {
let cipher = Cipher::aes_128_cbc(); let cipher = Cipher::aes_128_cbc();
let key = key.unwrap_or("welovenfts"); let key = key.unwrap_or("welovenfts");
let strength = strength.unwrap_or("default");
let iv_bytes = &input.to_string()[..10]; let iv_bytes = &input.to_string()[..10];
let iv = base64::encode(iv_bytes); let iv: String;
if strength == "default" {
iv = CUSTOM_ENGINE.encode(iv_bytes);
} else {
let num_bytes = 10; // Adjust this to the number of random bytes you need
let random_bytes = generate_random_bytes(num_bytes);
iv = CUSTOM_ENGINE.encode(random_bytes);
}
let mut padded_key = key.as_bytes().to_vec(); let mut padded_key = key.as_bytes().to_vec();
while padded_key.len() < 16 { while padded_key.len() < 16 {
padded_key.push(b'\0'); padded_key.push(b'\0');
} }
padded_key.truncate(16);
let ciphertext = encrypt(cipher, &padded_key, Some(iv.as_bytes()), input.as_bytes()).unwrap(); let ciphertext = encrypt(cipher, &padded_key, Some(iv.as_bytes()), input.as_bytes()).unwrap();
// Calculate HMAC
let hmac = calculate_hmac(&ciphertext, &padded_key); let hmac = calculate_hmac(&ciphertext, &padded_key);
// Constant-time compare HMAC to protect against timing attacks
if hmac.ct_eq(&calculate_hmac(&ciphertext, &padded_key)).unwrap_u8() == 1 { if hmac.ct_eq(&calculate_hmac(&ciphertext, &padded_key)).unwrap_u8() == 1 {
let mut result = iv.into_bytes(); let mut result = iv.into_bytes();
result.extend_from_slice(&hmac); result.extend_from_slice(&hmac);
result.extend_from_slice(&ciphertext); result.extend_from_slice(&ciphertext);
let encoded_result = encode(&result); let encoded_result = CUSTOM_ENGINE.encode(&result);
Some(encoded_result) Some(encoded_result)
} else { } else {
println!("Encryption HMAC validation failed"); println!("Encryption HMAC validation failed");
None None
} }
} }
pub mod hmac { pub mod hmac {
pub(crate) fn calculate_hmac(data: &[u8], key: &[u8]) -> Vec<u8> { pub(crate) fn calculate_hmac(data: &[u8], key: &[u8]) -> Vec<u8> {
use openssl::hash::MessageDigest; use openssl::hash::MessageDigest;
@ -71,3 +108,10 @@
signer.sign_to_vec().unwrap() signer.sign_to_vec().unwrap()
} }
} }
fn generate_random_bytes(num_bytes: usize) -> Vec<u8> {
let mut rng = OsRng;
let mut random_bytes = vec![0u8; num_bytes];
rng.fill(&mut random_bytes[..]);
random_bytes
}

View File

@ -2,6 +2,7 @@
pub mod encryption; pub mod encryption;
pub mod decryption; pub mod decryption;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::char_mappings::maps::mappings::{get_color, numbers_to_letter}; use crate::char_mappings::maps::mappings::{get_color, numbers_to_letter};
@ -14,7 +15,7 @@
#[test] #[test]
fn test_char_conversion() { fn test_char_conversion() {
// Define valid characters for testing // Define valid characters for testing
let valid_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"; let valid_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
for character in valid_characters.chars() { for character in valid_characters.chars() {
// Get the color for the character // Get the color for the character
let color_result = get_color(character); let color_result = get_color(character);
@ -42,7 +43,7 @@
// Your encryption key (replace with the actual key you use) // Your encryption key (replace with the actual key you use)
let key = Some("your_secret_key"); let key = Some("your_secret_key");
// Encrypt the input // Encrypt the input
let encrypted = encrypts(input, key.clone()); let encrypted = encrypts(input, key.clone(), None);
// Decrypt the encrypted data // Decrypt the encrypted data
let decrypted = decrypts(encrypted.as_ref().unwrap(), key); let decrypted = decrypts(encrypted.as_ref().unwrap(), key);
// Assert that decryption matches the original input // Assert that decryption matches the original input
@ -54,7 +55,7 @@
// Input data to encrypt // Input data to encrypt
let input = "ThisIsJustsTestString"; let input = "ThisIsJustsTestString";
// Encrypt the input without a key // Encrypt the input without a key
let encrypted = encrypts(input, None); let encrypted = encrypts(input, None, None);
// Decrypt the encrypted data without a key // Decrypt the encrypted data without a key
let decrypted = decrypts(encrypted.as_ref().unwrap(), None); let decrypted = decrypts(encrypted.as_ref().unwrap(), None);
// Assert that decryption matches the original input // Assert that decryption matches the original input
@ -69,7 +70,7 @@
let mut length = 1844674406; // Start with an initial length let mut length = 1844674406; // Start with an initial length
let max_length = 1844674407; // Set the maximum length let max_length = 1844674407; // Set the maximum length
while length <= max_length { while length <= max_length {
let encrypted = encrypts(&"A".repeat(length), key.clone()); let encrypted = encrypts(&"A".repeat(length), key.clone(), None);
let decrypted = decrypts(encrypted.as_ref().unwrap(), key.clone()); let decrypted = decrypts(encrypted.as_ref().unwrap(), key.clone());
if decrypted.is_none() { if decrypted.is_none() {
@ -100,7 +101,7 @@
// Your encryption key // Your encryption key
let key = Some("your_secret_key"); let key = Some("your_secret_key");
// Encrypt the input // Encrypt the input
let encrypted = encrypts(input, key.clone()); let encrypted = encrypts(input, key.clone(), None);
// Decrypt the encrypted data // Decrypt the encrypted data
let decrypted = decrypts(encrypted.as_ref().unwrap(), key); let decrypted = decrypts(encrypted.as_ref().unwrap(), key);
// Assert that decryption matches the original input // Assert that decryption matches the original input
@ -111,10 +112,20 @@
fn test_create_img_and_decode() { fn test_create_img_and_decode() {
let ciphertext = "ThisIsJustaTestString"; let ciphertext = "ThisIsJustaTestString";
let watermark = "Bitcoin"; // Text watermark let watermark = "Bitcoin"; // Text watermark
let style = "h";
// Create the image // Create the image
let encoded_image = create_img(ciphertext, watermark); let encoded_image = create_img(ciphertext, style, watermark, None, None, None, None, None, None);
// Print out the encoded image for debugging
println!("Encoded Image: {:?}", encoded_image);
// Decode the image and extract text // Decode the image and extract text
let extracted_text = decode_image_and_extract_text(&encoded_image.unwrap()); let extracted_text = decode_image_and_extract_text(&encoded_image.unwrap());
// Print out the extracted text for debugging
println!("Extracted Text: {:?}", extracted_text);
// Check if extracted text matches the original ciphertext // Check if extracted text matches the original ciphertext
assert_eq!(extracted_text, Some(ciphertext.to_string())); assert_eq!(extracted_text, Some(ciphertext.to_string()));
} }
@ -126,7 +137,7 @@
// Your encryption key (replace with the actual key you use) // Your encryption key (replace with the actual key you use)
let key = Some("your_secret_key"); let key = Some("your_secret_key");
// Encrypt the input // Encrypt the input
let encrypted = encrypts(input, key.clone()); let encrypted = encrypts(input, key.clone(), None);
// Print the encrypted string for testing // Print the encrypted string for testing
println!("Encrypted: {}", encrypted.as_ref().unwrap()); println!("Encrypted: {}", encrypted.as_ref().unwrap());
// Decrypt the encrypted data // Decrypt the encrypted data