SecureProps is a powerful PHP library designed to simplify the encryption and decryption of property data in objects.
Utilizing the power of PHP attributes, SecureProps allows developers to easily secure sensitive data within their applications. The library supports both asymmetric and symmetric encryption methods, providing flexibility in securing your application data.
- Easy-to-use encryption and decryption of properties within PHP objects.
- Support for asymmetric encryption using RSA keys.
- Support for symmetric encryption using Advanced Encryption Standard (AES-256-GCM).
- PHP 8.0 or higher.
- OpenSSL extension enabled in your PHP installation.
You can install SecureProps via Composer by running the following command:
composer require ilicmiljan/secure-props
Ensure that your composer.json
file is updated and the library is included in your project's dependencies.
Use the #[Encrypted]
attribute to mark properties for encryption. This attribute supports an optional placeholder
parameter for customizable decryption failure handling.
When decryption fails, and a placeholder
is provided, that value is used instead. If the placeholder is null,
an exception may be thrown.
use IlicMiljan\SecureProps\Attribute\Encrypted;
class User
{
#[Encrypted(placeholder: "***-**-****")]
private string $socialSecurityNumber;
#[Encrypted]
private string $secretNote;
}
To encrypt or decrypt objects, you will need to use the ObjectEncryptionService
. Here is an example:
use IlicMiljan\SecureProps\ObjectEncryptionService;
use IlicMiljan\SecureProps\Cipher\AdvancedEncryptionStandardCipher;
// Create a cipher instance (AES in this example)
$cipher = new AdvancedEncryptionStandardCipher('256-BIT-KEY-HERE');
// Initialize the encryption service with a runtime object properties reader
$encryptionService = new ObjectEncryptionService($cipher, new RuntimeObjectPropertiesReader());
$user = new User();
$user->setSocialSecurityNumber('123-45-6789');
// Encrypt properties
$encryptedUser = $encryptionService->encrypt($user);
// Decrypt properties
$decryptedUser = $encryptionService->decrypt($encryptedUser);
To use asymmetric encryption, initialize the AsymmetricEncryptionCipher
with your public and private keys:
use IlicMiljan\SecureProps\Cipher\AsymmetricEncryptionCipher;
$cipher = new AsymmetricEncryptionCipher($publicKey, $privateKey);
// Then, pass this cipher to the ObjectEncryptionService as shown above.
When working with objects that have properties with both encrypted and non-encrypted values, the TagAwareCipher
provides an advanced solution. This cipher allows for targeted decryption, operating only on encrypted and tagged
properties, which prevents errors when encountering non-encrypted data.
TagAwareCipher
automatically tags encrypted data with <ENC>
and </ENC>
, making it distinctly identifiable. It
specifically looks for these tags during the decryption process to determine which data to decrypt. This targeted
approach means that if an object contains tagged (encrypted) and untagged (plain) data, TagAwareCipher
will only
attempt to decrypt the tagged portions.
This avoids the risk of exceptions that typically occur when trying to decrypt data that isn't encrypted, ensuring error-free processing.
Important
When using TagAwareCipher
for decryption, it's crucial to understand that it will only decrypt data wrapped with
<ENC>
and </ENC>
tags.
If it encounters encrypted data without these tags, the decryption process will skip it, and the data will be returned in its encrypted form.
Here is an example:
// Initialize the base cipher with AES encryption.
// Optionally, attach a NullEncoder to prevent data double-encoding. Useful when
// the decorator cipher (e.g., TagAwareCipher) applies its own encoding.
$baseCipher = new AdvancedEncryptionStandardCipher('256-BIT-KEY-HERE', new NullEncoder());
// Initialize TagAwareCipher with your base cipher and an optional custom encoder.
$cipher = new TagAwareCipher($baseCipher, new Base64Encoder());
// Initialize the encryption service with a runtime object properties reader.
$encryptionService = new ObjectEncryptionService($cipher, new RuntimeObjectPropertiesReader());
$user = new User();
$user->setSocialSecurityNumber('123-45-6789');
// Encrypt properties
$encryptedUser = $encryptionService->encrypt($user);
// Decrypt properties
$decryptedUser = $encryptionService->decrypt($encryptedUser);
SecureProps provides two types of property readers to handle encrypted properties within your PHP objects efficiently: RuntimeObjectPropertiesReader
and CachingObjectPropertiesReader
.
The RuntimeObjectPropertiesReader
dynamically examines objects at runtime to identify properties decorated with the #[Encrypted]
attribute. Utilizing PHP's reflection requires no additional setup for caching and offers straightforward inspection capabilities.
For enhanced performance, especially in applications that frequently deal with the same types of objects, the CachingObjectPropertiesReader
caches property reading results. This approach reduces the computational overhead associated with reflection.
It integrates seamlessly with PSR-6
compliant caching solutions, allowing for customizable performance optimization.
Combining CachingObjectPropertiesReader
with RuntimeObjectPropertiesReader
and a PSR-6
compliant cache implementation:
// Initialize a PSR-6 cache pool
$cache = new FilesystemAdapter(...);
// Configure the caching reader
$reader = new CachingObjectPropertiesReader(
new RuntimeObjectPropertiesReader(),
new CacheItemPoolAdapter($cache)
);
// Set up the ObjectEncryptionService with the reader
$encryptionService = new ObjectEncryptionService($cipher, $reader);
Encoders are crucial components in the encryption and decryption process, transforming data into a format suitable for secure transmission or storage and then back to its original form.
The Base64Encoder
is designed for encoding binary data into a string of ASCII
characters, using the Base64 encoding scheme. This makes the data safe for
transmission over protocols that are not binary-safe.
The NullEncoder
serves as a pass-through, meaning it does not alter the input
data. This is particularly useful when you want to avoid double-encoding data
that is already in a suitable format for storage or when the encoding process
is managed elsewhere.
In the context of initializing the AdvancedEncryptionStandardCipher
with AES
encryption, you can optionally attach a custom encoder.
// Preventing double-encoding by using NullEncoder with the base cipher
$cipher = new AdvancedEncryptionStandardCipher('256-BIT-KEY-HERE', new NullEncoder());
// Initializing the encryption service with the configured cipher and property reader
$encryptionService = new ObjectEncryptionService($cipher, new RuntimeObjectPropertiesReader());
// Example of encrypting and decrypting user data
$user = new User();
$user->setSocialSecurityNumber('123-45-6789');
// Encrypt properties. The operation returns a string that is not binary-safe,
// and may require encoding to be safely transmitted or stored.
$encryptedUser = $encryptionService->encrypt($user);
// Decrypt properties
$decryptedUser = $encryptionService->decrypt($encryptedUser);
Note
Unless specified otherwise, all ciphers use Base64Encoder
as the default encoder to ensure the encrypted data is
binary-safe and suitable for transmission or storage across different systems.
Contributions to SecureProps are welcome. Please ensure that your code adheres to the project's coding standards and include tests for new features or bug fixes.
SecureProps is open-sourced software licensed under the MIT license.