Skip to content

Instantly share code, notes, and snippets.

@Mehrdad-Dadkhah
Created January 8, 2025 09:09
Show Gist options
  • Select an option

  • Save Mehrdad-Dadkhah/b3b99dc294d79120f9440590a46c6e59 to your computer and use it in GitHub Desktop.

Select an option

Save Mehrdad-Dadkhah/b3b99dc294d79120f9440590a46c6e59 to your computer and use it in GitHub Desktop.
Secure Image Encryption Class

Secure Image Encryption Class Analysis

The SecureImageEncryption class is designed for image encryption utilizing the AES-256-CBC algorithm. This class facilitates the secure storage of images in an encrypted format and provides the capability to decrypt them when needed.

Rationale for Image Encryption

Several critical reasons underpin the need for image encryption:

  • Data Protection: Images may contain sensitive information. Encryption prevents unauthorized access to this data, ensuring confidentiality.
  • Secure Storage: By encrypting images before storing them in a database or file system, the primary content remains unintelligible even if unauthorized access to the data occurs. This adds a crucial layer of security.
  • Access Control: Encryption keys enable controlled access to images, ensuring that only authorized individuals can view or utilize them.

Code Functionality Breakdown

  1. Class Constructor (__construct):

    • Accepts a baseSalt as input, storing it in the $this->baseSalt variable. This salt is used to generate encryption keys.
  2. generateKey(string $timestamp) Method:

    • Takes a timestamp as input.
    • Combines the baseSalt with the timestamp to create a composite salt.
    • Utilizes the hash_pbkdf2 function to generate a 32-byte encryption key. This function derives a key from the composite salt, which is then used for encryption.
    • The use of hash_pbkdf2 enhances the strength and resilience of the generated key against brute-force attacks.
  3. encrypt(string $imagePath) Method:

    • Receives the image path as input.
    • Reads the image content using file_get_contents.
    • Generates a timestamp using time().
    • Generates an encryption key based on the timestamp using the generateKey method.
    • Creates a random Initialization Vector (IV) using openssl_random_pseudo_bytes. This IV is essential for the AES-256-CBC encryption algorithm.
    • Encrypts the image using openssl_encrypt with the generated key and IV.
    • Returns the encrypted data, IV, and timestamp, all encoded using base64.
  4. decrypt(string $encryptedData, string $iv, string $timestamp) Method:

    • Receives the encrypted data, IV, and timestamp as input.
    • Generates an encryption key based on the timestamp using the generateKey method.
    • Decrypts the encrypted data using openssl_decrypt with the generated key and IV.
    • Throws an exception if decryption fails.
    • Returns the decrypted data.
  5. Usage Example:

    • A baseSalt is defined.
    • An instance of the SecureImageEncryption class is created.
    • The encrypt method is called to encrypt an image.
    • The encrypted data, IV, and timestamp are stored in a database.
    • This example utilizes PDO for connecting to a MySQL database.

Critical Security Considerations

  • Strong baseSalt: The baseSalt must be highly complex and unique. Avoid using simple or predictable salts.
  • Secure baseSalt Storage: The baseSalt should not be stored in the code or publicly accessible files. It is best practice to store it in a secure environment, such as environment variables or a secure configuration file.
  • Use of hash_pbkdf2: Employing hash_pbkdf2 significantly enhances the security of the generated keys.
  • Initialization Vector (IV): Generating a random IV for each encryption is crucial.
  • AES-256-CBC Encryption: AES-256-CBC is a robust encryption algorithm, but it must be implemented correctly to ensure security.

Database Table Structure

  • id: A unique identifier for each record.
  • encrypted_data: The encrypted image data.
  • iv: The Initialization Vector used for encryption.
  • encryption_timestamp: The timestamp of the encryption.
  • created_at: The record creation timestamp.

Summary

This class provides a secure method for encrypting and decrypting images. By utilizing a strong baseSalt, the hash_pbkdf2 key derivation function, and the AES-256-CBC encryption algorithm, it ensures the security of images against unauthorized access. However, adherence to the aforementioned security considerations is paramount for maintaining data integrity and confidentiality.

<?php
class SecureImageEncryption {
private string $baseSalt; // Base salt used for key generation
private string $cipher = "aes-256-gcm"; // Use GCM mode for encryption, which is more secure than CBC
// Constructor to initialize the base salt
public function __construct(string $baseSalt) {
$this->baseSalt = $baseSalt; // Set the base salt for the instance
}
// Generates a secure key using PBKDF2 with the provided salt
private function generateKey(string $salt): string {
return hash_pbkdf2(
"sha256", // Hash algorithm
$this->baseSalt, // Base salt
$salt, // Salt for this specific key
10000, // Number of iterations
32, // Length of the derived key in bytes
true // Output as raw binary data
);
}
// Encrypts the image at the specified path
public function encrypt(string $imagePath): array {
// Check if the image file exists
if (!file_exists($imagePath)) {
throw new Exception('Image file not found.'); // Throw an exception if the file is not found
}
// Read the content of the image file
$imageContent = file_get_contents($imagePath);
// Generate a random salt for this encryption
$salt = random_bytes(16); // Generate 16 bytes of random data
// Generate a secure key using the random salt
$key = $this->generateKey($salt);
// Generate a random nonce for GCM mode
$nonce = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->cipher));
// Encrypt the image content using the generated key and nonce
$encrypted = openssl_encrypt(
$imageContent, // Data to encrypt
$this->cipher, // Cipher method
$key, // Encryption key
OPENSSL_RAW_DATA, // Output raw binary data
$nonce, // Nonce for GCM
$tag // Variable to hold the authentication tag
);
// Return the encrypted data, nonce, salt, and tag encoded in base64
return [
'data' => base64_encode($encrypted), // Encrypted data
'nonce' => base64_encode($nonce), // Nonce used for encryption
'salt' => base64_encode($salt), // Salt used for key generation
'tag' => base64_encode($tag) // Authentication tag for GCM
];
}
// Decrypts the encrypted data using the provided nonce, salt, and tag
public function decrypt(string $encryptedData, string $nonce, string $salt, string $tag): string {
// Reconstruct the key using the provided salt
$key = $this->generateKey(base64_decode($salt));
// Decrypt the data using the key and nonce
$decrypted = openssl_decrypt(
base64_decode($encryptedData), // Encrypted data
$this->cipher, // Cipher method
$key, // Decryption key
OPENSSL_RAW_DATA, // Output raw binary data
base64_decode($nonce), // Nonce used for encryption
base64_decode($tag) // Authentication tag for GCM
);
// Check if decryption failed
if ($decrypted === false) {
throw new Exception('Decryption failed'); // Throw an exception if decryption fails
}
return $decrypted; // Return the decrypted data
}
}
// Database table structure for storing encrypted images
/*
CREATE TABLE secure_images (
id INT AUTO_INCREMENT PRIMARY KEY, // Unique identifier for each record
encrypted_data LONGTEXT NOT NULL, // Column to store encrypted image data
nonce VARCHAR(255) NOT NULL, // Column to store nonce used in encryption
salt VARCHAR(255) NOT NULL, // Column to store salt used for key generation
tag VARCHAR(255) NOT NULL, // Column to store authentication tag
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP // Column to store the timestamp of record creation
);
*/
// Example usage for storing encrypted images
try {
$baseSalt = 'Your_Very_Complex_Salt_Here_123!@#'; // Define a complex base salt
$encryption = new SecureImageEncryption($baseSalt); // Create an instance of the SecureImageEncryption class
// Encrypt the image located at the specified path
$encryptedData = $encryption->encrypt('/path/to/image.jpg');
// Store the encrypted data in the database
$pdo = new PDO("mysql:host=localhost;dbname=your_db", "username", "password"); // Create a new PDO instance for database connection
$stmt = $pdo->prepare("
INSERT INTO secure_images (encrypted_data, nonce, salt, tag)
VALUES (:data, :nonce, :salt, :tag) // Prepare the SQL statement for insertion
");
// Execute the prepared statement with the encrypted data and other parameters
$stmt->execute([
'data' => $encryptedData['data'], // Encrypted image data
'nonce' => $encryptedData['nonce'], // Nonce used for encryption
'salt' => $encryptedData['salt'], // Salt used for key generation
'tag' => $encryptedData['tag'] // Authentication tag
]);
} catch (Exception $e) {
echo "Error: " . $e->getMessage(); // Output error message if an exception occurs
}
class ImageEncryption {
private string $salt;
public function __construct(string $salt) {
$this->salt = $salt;
}
public function encrypt(string $imagePath): string {
// خواندن تصویر به صورت باینری
$imageContent = file_get_contents($imagePath);
// XOR با salt
$encrypted = $this->xorEncrypt($imageContent, $this->salt);
// تبدیل به base64
return base64_encode($encrypted);
}
public function decrypt(string $encryptedData): string {
// برگرداندن از base64
$decoded = base64_decode($encryptedData);
// برگرداندن XOR با همان salt
return $this->xorEncrypt($decoded, $this->salt);
}
private function xorEncrypt(string $data, string $salt): string {
$dataLength = strlen($data);
$saltLength = strlen($salt);
$encrypted = '';
for ($i = 0; $i < $dataLength; $i++) {
$encrypted .= $data[$i] ^ $salt[$i % $saltLength];
}
return $encrypted;
}
}

SecureImageEncryption عملکرد کلی:

کلاس SecureImageEncryption برای رمزنگاری تصاویر با استفاده از الگوریتم AES-256-CBC طراحی شده است. این کلاس تصاویر را به صورت رمزنگاری شده ذخیره می‌کند و امکان رمزگشایی آن‌ها را فراهم می‌سازد.

چرا این کار انجام می‌شود؟

  1. حفاظت از داده‌ها: تصاویر ممکن است حاوی اطلاعات حساس باشند. رمزنگاری از دسترسی غیرمجاز به این اطلاعات جلوگیری می‌کند.
  2. امنیت در ذخیره‌سازی: با رمزنگاری تصاویر قبل از ذخیره‌سازی در پایگاه داده یا سیستم فایل، حتی اگر دسترسی غیرمجاز به داده‌ها وجود داشته باشد، محتوای اصلی تصاویر قابل فهم نخواهد بود.
  3. کنترل دسترسی: با استفاده از کلیدهای رمزنگاری، می‌توان دسترسی به تصاویر را کنترل کرد و اطمینان حاصل کرد که فقط افراد مجاز می‌توانند به آن‌ها دسترسی داشته باشند.

چگونگی کارکرد کد:

  1. سازنده کلاس (__construct):

    • یک baseSalt به عنوان ورودی می‌گیرد و آن را در متغیر $this->baseSalt ذخیره می‌کند. این salt برای ایجاد کلیدهای رمزنگاری استفاده می‌شود.
  2. متد generateKey(string $timestamp):

    • این متد یک timestamp به عنوان ورودی می‌گیرد.
    • baseSalt را با timestamp ترکیب می‌کند تا یک salt ترکیبی ایجاد کند.
    • از تابع hash_pbkdf2 برای تولید یک کلید رمزنگاری 32 بایتی استفاده می‌کند. این تابع یک کلید مشتق شده از salt ترکیبی ایجاد می‌کند که به عنوان کلید رمزنگاری استفاده می‌شود.
    • استفاده از hash_pbkdf2 باعث می‌شود که کلید تولید شده قوی‌تر و مقاوم‌تر در برابر حملات brute-force باشد.
  3. متد encrypt(string $imagePath):

    • مسیر تصویر را به عنوان ورودی دریافت می‌کند.
    • محتوای تصویر را با استفاده از file_get_contents می‌خواند.
    • یک timestamp با استفاده از time() ایجاد می‌کند.
    • با استفاده از متد generateKey یک کلید رمزنگاری بر اساس timestamp تولید می‌کند.
    • یک بردار اولیه (IV) تصادفی با استفاده از openssl_random_pseudo_bytes تولید می‌کند. این بردار اولیه برای الگوریتم رمزنگاری AES-256-CBC ضروری است.
    • با استفاده از تابع openssl_encrypt تصویر را با کلید و بردار اولیه رمزنگاری می‌کند.
    • داده‌های رمزنگاری شده، بردار اولیه و timestamp را به صورت base64_encode شده برمی‌گرداند.
  4. متد decrypt(string $encryptedData, string $iv, string $timestamp):

    • داده‌های رمزنگاری شده، بردار اولیه و timestamp را به عنوان ورودی دریافت می‌کند.
    • با استفاده از متد generateKey یک کلید رمزنگاری بر اساس timestamp تولید می‌کند.
    • با استفاده از تابع openssl_decrypt داده‌های رمزنگاری شده را با کلید و بردار اولیه رمزگشایی می‌کند.
    • اگر رمزگشایی ناموفق باشد، یک استثنا پرتاب می‌کند.
    • داده‌های رمزگشایی شده را برمی‌گرداند.
  5. مثال استفاده:

    • یک baseSalt تعریف شده است.
    • یک شی از کلاس SecureImageEncryption ایجاد می‌شود.
    • متد encrypt برای رمزنگاری یک تصویر فراخوانی می‌شود.
    • داده‌های رمزنگاری شده، بردار اولیه و timestamp در یک پایگاه داده ذخیره می‌شوند.
    • در این مثال از PDO برای اتصال به پایگاه داده MySQL استفاده شده است.

نکات امنیتی مهم:

  • baseSalt قوی: baseSalt باید بسیار پیچیده و منحصر به فرد باشد. از salt های ساده و قابل حدس زدن خودداری کنید.
  • ذخیره‌سازی امن baseSalt: baseSalt نباید در کد یا فایل‌های قابل دسترس عموم ذخیره شود. بهتر است آن را در یک محیط امن مانند متغیرهای محیطی یا یک فایل پیکربندی امن ذخیره کنید.
  • استفاده از hash_pbkdf2: استفاده از hash_pbkdf2 باعث افزایش امنیت کلیدهای تولید شده می‌شود.
  • بردار اولیه (IV): تولید بردار اولیه تصادفی برای هر رمزنگاری ضروری است.
  • رمزنگاری AES-256-CBC: الگوریتم AES-256-CBC یک الگوریتم رمزنگاری قوی است، اما باید به درستی استفاده شود.

ساختار جدول دیتابیس:

  • id: شناسه یکتای هر رکورد.
  • encrypted_data: داده‌های رمزنگاری شده تصویر.
  • iv: بردار اولیه (IV) استفاده شده در رمزنگاری.
  • encryption_timestamp: timestamp زمان رمزنگاری.
  • created_at: زمان ایجاد رکورد.

خلاصه:

این کلاس یک روش امن برای رمزنگاری و رمزگشایی تصاویر ارائه می‌دهد. با استفاده از یک baseSalt قوی، الگوریتم hash_pbkdf2 برای تولید کلید، و الگوریتم رمزنگاری AES-256-CBC، امنیت تصاویر را در برابر دسترسی‌های غیرمجاز تضمین می‌کند. با این حال، توجه به نکات امنیتی ذکر شده برای حفظ امنیت داده‌ها ضروری است.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment