This class is designed to provide secure and easy to use file encryption. This class uses encryption that is compatible with most Linux, Unix, and Mac computers using command line calls on the OS with [openssl]. This class and has the ability to encrypt both large on-disk files and smaller in-memory files. Very large files of any size can be encrypted on when using the default command line settings.
As of 2019 file encryption has been tested and confirmed on recent versions the following operating systems using the default or minimal OS setup and PHP:
macOS, Windows, Ubuntu, Debian, Amazon Linux, CentOS, openSUSE, Fedora,
Red Hat Enterprise Linux, Windows using Windows Subsystem for Linux
Large file encryption with FreeBSD may or may not work depending on which shell commands are avaiable and which version of FreeBSD is used. If you intended on using this class with FreeBSD for large file encryption make sure your server passes all crypto unit tests.
A compatible Bash Script available on the main site at [scripts/shell/bash/encrypt.sh].
Security - Encrypt and Decrypt a File
// FastSitePHP allows for fast authenticated encryption of any size file // (even large files that are many gigs in size). The code used for encryption // is compatible with shell commands and a Bash Script [encrypt.sh] that works // on Linux and Unix Computers. The Bash Script can be downloaded from this site, // and will work on most Linux OS's without having to install anything. // Generate a Key for Encryption $crypto = new \FastSitePHP\Security\Crypto\FileEncryption(); $key = $crypto->generateKey(); // Build file paths of files to save based on the original name $enc_file = $file_path . '.enc'; $output_file = $enc_file . '.decrypted'; // Encrypt and Decrypt using the Crypto Helper Class with Config Settings. // A [FileEncryption] class also exists with additional options. $app->config['ENCRYPTION_KEY'] = $key; \FastSitePHP\Security\Crypto::encryptFile($file_path, $enc_file); \FastSitePHP\Security\Crypto::decryptFile($enc_file, $output_file);
Return a new key in hex format based on the size of the needed key. Keys are generated using random bytes from the System's CSPRNG (Cryptographically secure pseudorandom number generator).
The same key must be used for both encryption and decryption and the key should be kept secret in a secure manner and should not be shared publicly.
encryptFile($file_path, $enc_file, $key)
Encrypt a file
This function takes an input plaintext file and an output file of where to save the encrypted file. The file path for the encrypted file must refer to a file that does not yet exist. This function returns nothing and raises an exception in the event of an error.
The key is a string value in hexadecimal format that can be securely generated using [generateKey()].
If encrypting large files call [processFilesWithCmdLine(true)] or use the helper [Crypto] class instead. See additional comments below.
If using this Red Hat Linux you will likely first have to install the [xxd] command using [sudo yum install vim-common]. By default [xxd] is expected to exist on most Linux and Unix OS's.
IMPORTANT - File paths should generally not be passed user parameters because a user could specify files other than the intended file. If an App does need to allow the user to specify a file then the code should be carefully reviewed and tested for security.
Function Properties used with [encryptFile()] and [decryptFile()]:
Create a secure key
Set to [true] to show error detail on command line errors.
IMPORTANT - this should only be used for debugging as it can show
security info such as file paths and the key in the error message.
By default files are processed in memory. If this is set to [true]
then files are encrypted using shell commands. [true] will work with
most *nix OS's (Unix, Linux, macOS, etc); [false] is the only option that
will work with Windows. Small files can be processed in memory much
faster than using shell commands, however when using shell commands
large files (Gigs in size) can be processed.
Functions that change how Crypto Works:
[keyType()] - 'key' or 'password' - Default to 'key'
[pbkdf2Algorithm()] - For use with 'password' Key type
[pbkdf2Iterations()] - For use with 'password' Key type
[encryptThenAuthenticate()] - Set to [false] to disable Authentication
decryptFile($enc_file, $output_file, $key)
Decrypt a file
This function returns nothing and if the file cannot be decrypted an exception is thrown.
See comments in [encryptFile()] because the same properties and settings are used here.
If either [encryptFile()] or [decryptFile()] fails this function can be used to check the setup on the current computer or server. It returns relevant information for debugging such as the file path of all used commands, the current user, and the path variable.
Example of Data Returned:
The return property [getenforce] checks if Security-Enhanced Linux (SELinux) is installed. SELinux is included with various Linux OS's including Red Hat Enterprise Edition and CoreOS. SELinux provides additional security features that can prevent Apache and PHP from writing files unless configured to allow writing. If the shell command [getenforce] runs then SELinux is installed. Permissions may vary system to system however one example to allow writing by Apache/PHP to the directory [/var/www/data] and subdirectories is this:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/app_data(/.*)?"
sudo restorecon -Rv /var/www/app_data
sudo chown apache:apache -R /var/www/app_data/*
displayCmdErrorDetail($new_value = null)
Get or set error detail level.
When preforming command line file encryption and decryption this property can be set to true to provide detailed information including the command called with the error message.
IMPORTANT - This property is intended only for developers during development because the encryption key can be displayed with the error message if the command that has an error includes it.
Returns: bool | $this
processFilesWithCmdLine($new_value = null)
Get or set option on how to process files. Defaults to [false].
When set to [true] file encryption with will be done through command line calls on the OS using [openssl]. This allows for efficient streaming of large files during encryption and description and on most systems allows for files of any size (limited by the OS) to be encrypted. Command line file encryption can be done on most Linux, Unix, and Mac computers.
When set to [false] then file encryption will be handled in-memory using settings that are compatible with [openssl] command line.
When set to [false] file encryption will be faster for small files however the entire file is loaded in memory so it should only be used on small files or based on the needs of your app and server.
To perform file encryption on Windows this must be set to [false] because command line encryption is currently not supported on Windows.
WARNING - setting [processFilesWithCmdLine(true)] is currently not recommended when using FreeBSD unless your server passes all crypto unit tests.
Returns: bool | $this
If using PHP 5.3 then functions [bin2hex()] and [hex2bin()] and OpenSSL Constant [OPENSSL_RAW_DATA] are polyfilled.
If using PHP 5.5 or below then [hash_equals()] is polyfilled.
encryptThenAuthenticate($new_value = null)
Get or set whether to use authenticated encryption. When set to [true] text or data is encrypted using the specified encryption algorithm (default 'aes-256-cbc') then the encrypted bytes are hashed using hmac with the specified hashing algorithm (default 'sha256'). If set to [false] then data or text is only encrypted and the decrypted data cannot be verified if it has been tampered with or not. Authenticating encrypted data is a critical step for data integrity so it's important that this property should be left as the default value [true] unless compatibility with data encrypted outside of this class is needed.
Returns: bool | $this
keyType($new_value = null)
Get or set the key type which is a string value of either 'key' or 'password'. The default value is 'key' which results in encryption functions validating that the key parameter used for encryption and decryption to match the required length. When using 'password' then keys are generated each time from PBKDF2 (Password-Based Key Derivation Function 2). PBKDF2 takes a considerable amount of CPU so using the 'password' option requires carefull consideration as it can make a site more susceptible to Denial of Service (DoS) attacks if a lot of requests are sent to service or page that uses PBKDF2.
Returns: string | $this
pbkdf2Algorithm($new_value = null)
Get or set the PBKDF2 Hashing Algorithm to use with the option [keyType('password')]. Defaults to 'sha512'. Only Algorthims allowed for PHP function [hash_pbkdf2()] are supported.
Returns: string | $this
pbkdf2Iterations($new_value = null)
Get or set the number of PBKDF2 iterations to use with option [keyType('password')]. Defaults to 200000 [200,000].
If you have an older server 200,000 might be too slow and you could use 100,000, however if you change this setting you would need to track what was encrypted with a different number.
Returns: int | $this