src/Encryption/Encryption.php
<?php
/**
* The PHP Simple Encryption library is designed to simplify the process of encrypting and decrypting data while
* ensuring best practices are followed. By default, it uses a secure encryption algorithm and generates a
* cryptologically strong initialization vector so developers do not need to become experts in encryption to securely
* store sensitive data.
*
* @author John Conde <stymiee@gmail.com>
* @example https://www.johnconde.net/blog/php-simple-encryption/ PHP Simple Encryption
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://github.com/stymiee/php-simple-encryption
* @version 1.0.7
*/
declare(strict_types=1);
namespace Encryption;
use Encryption\Cipher\ACipher;
use Encryption\Exceptions\CipherNotImplementedException;
use Encryption\Exceptions\InvalidCipherException;
use Encryption\Exceptions\InvalidVersionException;
/**
* Class Encryption
* @package Encryption
*/
class Encryption
{
public const DEFAULT_CIPHER = 'AES-256-CBC';
/**
* @since 1.0.2
*/
public const VERSION = 1;
/**
* Builds and returns an encryption object with the specified cipher. Defaults to the default cipher which will
* change with each version of this library.
*
* @param string|null $cipher
* @return ACipher
* @throws CipherNotImplementedException
* @throws InvalidCipherException
* @uses Encryption::createEncryptionObject
* @uses Encryption::getCipherMethods
*/
public static function getEncryptionObject(?string $cipher = null): ACipher
{
$cipher = strtolower($cipher ?: static::DEFAULT_CIPHER);
$availableCiphers = static::getCipherMethods();
if (!in_array($cipher, $availableCiphers, true)) {
$message = sprintf('Invalid cipher selected [%s]', $cipher);
throw new InvalidCipherException($message);
}
return static::createEncryptionObject($cipher);
}
/**
* Returns a unique list of ciphers on the system in lowercase.
*
* @return array
*/
public static function getCipherMethods(): array
{
return array_unique(array_map('strtolower', openssl_get_cipher_methods()));
}
/**
* Builds the class name for the specified cipher.
*
* @param string $cipher
* @return string
*/
protected static function createClassName(string $cipher): string
{
$crypto = strtoupper(explode('-', $cipher)[0]);
return sprintf(
'%s\%s\%s',
'Encryption\Cipher',
$crypto,
str_replace('-', '', ucwords($cipher))
);
}
/**
* Creates the encryption object using the specified cipher.
*
* @param string $cipher
* @return ACipher
* @throws CipherNotImplementedException
*@uses Encryption::createClassName
*/
protected static function createEncryptionObject(string $cipher): ACipher
{
$className = static::createClassName($cipher);
if (!class_exists($className)) {
$message = sprintf('Cipher [%s] has not been implemented yet', $cipher);
throw new CipherNotImplementedException($message);
}
return new $className();
}
/**
* Returns all ciphers that are available on the system AND is supported by this library.
*
* @return array
* @uses Encryption::createClassName
* @uses Encryption::getCipherMethods
*/
public static function listAvailableCiphers(): array
{
$availableCiphers = [];
foreach (static::getCipherMethods() as $cipher) {
$className = static::createClassName($cipher);
if (class_exists($className)) {
$availableCiphers[] = $cipher;
}
}
return $availableCiphers;
}
/**
* Returns the default cipher for a specified version. Defaults to the current version if no version is specified.
*
* @param int $version
* @return string
* @throws InvalidVersionException
*/
public static function getDefaultCipherByVersion(int $version = self::VERSION): string
{
$defaultCiphers = [
self::VERSION => self::DEFAULT_CIPHER,
];
if (isset($defaultCiphers[$version])) {
return $defaultCiphers[$version];
}
throw new InvalidVersionException(sprintf('Invalid version: [%s]', $version));
}
}