class AES in AES encryption 8.2
Hierarchy
- class \Drupal\aes\AES
Expanded class hierarchy of AES
3 files declare their use of AES
- aes.install in ./
aes.install - Install/uninstall handling for AES.
- AesAdminForm.php in src/
Form/ AesAdminForm.php - AesTests.php in src/
Tests/ AesTests.php
1 string reference to 'AES'
File
- src/
AES.php, line 10
Namespace
Drupal\aesView source
class AES {
/**
* Retrieve information about available AES implementations.
*
* @return array
*/
public static function get_available_implementations() {
$phpsec_available = FALSE;
if (\Drupal::moduleHandler()
->moduleExists('libraries') && libraries_get_path('phpseclib')) {
$phpsec_include_path = libraries_get_path('phpseclib');
set_include_path(get_include_path() . PATH_SEPARATOR . $phpsec_include_path);
$phpsec_available = is_readable($phpsec_include_path . '/Crypt/AES.php');
}
$mcrypt_available = extension_loaded('mcrypt');
return array(
'mcrypt' => $mcrypt_available,
'phpseclib' => $phpsec_available,
);
}
/**
* Load PHPSecLib files.
*
* @param bool $display_errors
* In case of problem with loading library, display errors and warnings.
*
* @return bool loading result
*/
public static function load_phpsec($display_errors = TRUE) {
$library_error = FALSE;
if (!\Drupal::moduleHandler()
->moduleExists('libraries')) {
$library_error = t('The Libraries module should be enabled to use phpseclib.');
}
elseif (($phpsec_include_path = libraries_get_path('phpseclib')) == FALSE) {
$library_error = t('The phpseclib package should be installed as a library.');
}
elseif (!file_exists($phpsec_include_path . '/Crypt/AES.php')) {
$library_error = t('Cannot load /Crypt/AES.php from phpseclib root.');
}
elseif (!is_readable($phpsec_include_path . '/Crypt/AES.php')) {
$library_error = t("It appears that phpseclib is installed in the right location but can't be read. Check that the permissions on the directory and its files allows for reading by the webserver.");
}
elseif (!function_exists('set_include_path')) {
$library_error = t('The set_include_path function is inaccessible.');
}
if ($library_error) {
if ($display_errors) {
drupal_set_message($library_error, 'warning');
}
return FALSE;
}
// Include phpsec AES lib.
set_include_path(get_include_path() . PATH_SEPARATOR . $phpsec_include_path);
include_once 'Crypt/AES.php';
if (class_exists('Crypt_AES')) {
return TRUE;
}
if ($display_errors) {
drupal_set_message('Including library error', 'error');
}
return FALSE;
}
/**
* Retrieve encryption key. Note we're using YAML files not DB settings.
*
* @return string encryption key.
*/
public static function get_key() {
$config = FileStorageFactory::getActive()
->read('aes.settings');
return isset($config['key']) ? $config['key'] : FALSE;
}
/**
* Generate a random key, containing uppercase, lowercase and digits.
*
* @return string encryption key.
*/
public static function make_key() {
$keylen = 32;
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
while (TRUE) {
$key = '';
while (strlen($key) < $keylen) {
$key .= substr($chars, rand(0, strlen($chars)), 1);
}
// is there at least one lowercase letter?
if (!preg_match('/.*[a-z].*/', $key)) {
continue;
}
// is there at least one uppercase letter?
if (!preg_match('/.*[A-Z].*/', $key)) {
continue;
}
// is there at least one numeric?
if (!preg_match('/.*[0-9].*/', $key)) {
continue;
}
break;
}
\Drupal::logger('aes')
->notice('Generated new AES key: ' . substr($key, 0, 4) . str_repeat('*', $keylen - 8) . substr($key, $keylen - 4, 4));
return $key;
}
/**
* Generate an IV - initialization vector - and store it in configuration.
*
* @param bool $ignore_implementation
*/
public static function make_iv($ignore_implementation = FALSE) {
$config = FileStorageFactory::getActive()
->read('aes.settings');
// Bail out if using phpseclib
if ($config['implementation'] == 'phpseclib' && $ignore_implementation == FALSE) {
\Drupal::logger('aes')
->warning("Called make_iv when using phpseclib. This is harmless, but shouldn't happen.");
return;
}
$randgen = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? MCRYPT_RAND : MCRYPT_DEV_URANDOM;
$cryptor = mcrypt_module_open($config['cipher'], '', MCRYPT_MODE_CBC, '');
if (!$cryptor) {
\Drupal::logger('aes')
->warning(t('Problem while calling mcrypt_module_open for cipher %cipher.'), array(
'%cipher' => $config['cipher'],
));
return;
}
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cryptor), $randgen);
mcrypt_module_close($cryptor);
$config['mcrypt_iv'] = base64_encode($iv);
FileStorageFactory::getActive()
->write('aes.settings', $config);
}
/**
* Encrypts a string.
*
* @param string $string
* The string to encrypt.
* @param bool $base64encode
* Whether to return the string base64 encoded (recommended for database insertion).
* @param string $custom_key
* Use this as the key rather than the stored one for this operation.
* @param string $custom_cipher
* Use this cipher rather than the default one. (only with Mcrypt - ignored with phpseclib)
* @param string $custom_iv
* Use this initialization vector instead of the default one.
* @param string $force_implementation
* Can be 'phpseclib', 'mcrypt' or classname of custom implementation. Warning: Does not check if the requested implementation actually exists.
*
* @return bool|string
* The encrypted string on success, false on error.
*/
public static function encrypt($string, $base64encode = TRUE, $custom_key = NULL, $custom_cipher = NULL, $custom_iv = NULL, $force_implementation = NULL) {
// Bail out if the passed string is empty.
if (empty($string)) {
\Drupal::logger('aes')
->warning('Tried to encrypt an empty string.');
return FALSE;
}
$config = FileStorageFactory::getActive()
->read('aes.settings');
$cipher = empty($custom_cipher) ? $config['cipher'] : $custom_cipher;
$key = empty($custom_key) ? self::get_key() : $custom_key;
$implementation = $force_implementation ? $force_implementation : $config['implementation'];
if ($implementation == 'phpseclib') {
// The phpseclib doesn't support custom ciphers and iv's.
if (!empty($custom_cipher)) {
\Drupal::logger('aes')
->warning("A custom cipher was defined when encrypting a string in the AES module using the phpseclib implementation. This implementation doesn't support custom ciphers therefore the argument was ignored and the encryption was done with the standard cipher.");
}
if (!empty($custom_iv)) {
\Drupal::logger('aes')
->warning("A custom IV was defined when encrypting a string in the AES module using the phpseclib implementation. This implementation doesn't support custom IV's therefore the argument was ignored and the encryption was done with the standard IV.");
}
if (!self::load_phpsec()) {
return FALSE;
}
$phpsec = new \Crypt_AES();
$phpsec
->setKey($key);
$encrypted = $phpsec
->encrypt($string);
return $base64encode ? base64_encode($encrypted) : $encrypted;
}
if ($implementation == 'mcrypt') {
// @todo remove this because we have Mcrypt plugin.
$td = mcrypt_module_open($cipher, '', MCRYPT_MODE_CBC, '');
$iv = base64_decode($custom_iv ? $custom_iv : $config['mcrypt_iv']);
if (empty($iv)) {
self::make_iv();
$config = FileStorageFactory::getActive()
->read('aes.settings');
$iv = base64_decode($config['mcrypt_iv']);
\Drupal::logger('aes')
->warning('No initialization vector found while trying to encrypt! Recreated a new one now and will try to carry on as normal.');
}
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1($key), 0, $ks);
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $string);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $base64encode ? base64_encode($encrypted) : $encrypted;
}
/* @var \Drupal\aes\Plugin\AESPluginManager $plugin_manager */
$plugin_manager = \Drupal::service('plugin.manager.aes');
try {
/* @var \Drupal\aes\Plugin\AESPluginBase $custom */
$custom = $plugin_manager
->getInstanceById($implementation);
$encrypted = $custom
->encrypt($string, $key, $cipher);
} catch (\Exception $e) {
$error_msg = t('AES having problems with custom plugin implementation: %plugin . Message: %msg', array(
'%plugin' => $implementation,
'%msg' => $e
->getMessage(),
));
\Drupal::logger('aes')
->error($error_msg);
return FALSE;
}
return $base64encode ? base64_encode($encrypted) : $encrypted;
}
/**
* Decrypts a string of encrypted data.
*
* @param string $string
* The string to decrypt.
* @param bool $base64encoded
* Whether this encrypted string is base64 encoded or not.
* @param string $custom_key
* Use this as the key rather than the stored one for this operation.
* @param string $custom_cipher
* Use this cipher rather than the default one. (only with Mcrypt - ignored with phpseclib)
* @param string $custom_iv
* Use this initialization vector instead of the default one.
* @param string $force_implementation
* Can be 'phpseclib', 'mcrypt' or classname of custom implementation. Warning: Does not check if the requested implementation actually exists.
*
* @return bool|string
* The decrypted string on success, false on error.
*/
public static function decrypt($string, $base64encoded = TRUE, $custom_key = NULL, $custom_cipher = NULL, $custom_iv = NULL, $force_implementation = NULL) {
// Bail out if the passed string is empty.
if (empty($string)) {
\Drupal::logger('aes')
->warning('Tried to decrypt an empty string.');
return FALSE;
}
$config = FileStorageFactory::getActive()
->read('aes.settings');
if ($base64encoded) {
$string = base64_decode($string);
}
$cipher = empty($custom_cipher) ? $config['cipher'] : $custom_cipher;
$key = empty($custom_key) ? self::get_key() : $custom_key;
$implementation = $force_implementation ? $force_implementation : $config['implementation'];
if ($implementation == 'phpseclib') {
// The phpseclib doesn't support custom ciphers and iv's.
if (!empty($custom_cipher)) {
\Drupal::logger('aes')
->warning("A custom cipher was defined when decrypting a string in the AES module using the phpseclib implementation. This implementation doesn't support custom ciphers therefore the argument was ignored and the decryption was done with the standard cipher.");
}
if (!empty($custom_iv)) {
\Drupal::logger('aes')
->warning("A custom IV was defined when decrypting a string in the AES module using the phpseclib implementation. This implementation doesn't support custom IV's therefore the argument was ignored and the decryption was done with the standard IV.");
}
if (!self::load_phpsec()) {
return FALSE;
}
$phpsec = new \Crypt_AES();
$phpsec
->setKey($key);
$decrypted = $phpsec
->decrypt($string);
return trim($decrypted);
}
if ($implementation == 'mcrypt') {
// @todo remove this because we have Mcrypt plugin.
$td = mcrypt_module_open($cipher, '', MCRYPT_MODE_CBC, '');
$ks = mcrypt_enc_get_key_size($td);
$iv = base64_decode($custom_iv ? $custom_iv : $config['mcrypt_iv']);
if (empty($iv)) {
\Drupal::logger('aes')
->error('No initialization vector found while trying to decrypt with mcrypt. Aborting!');
return FALSE;
}
$key = substr(sha1($key), 0, $ks);
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $string);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return trim($decrypted);
}
/* @var \Drupal\aes\Plugin\AESPluginManager $plugin_manager */
$plugin_manager = \Drupal::service('plugin.manager.aes');
try {
/* @var \Drupal\aes\Plugin\AESPluginBase $custom */
$custom = $plugin_manager
->getInstanceById($implementation);
$decrypted = $custom
->decrypt($string, $key, $cipher);
} catch (\Exception $e) {
$error_msg = t('AES having problems with custom plugin implementation: %plugin . Message: %msg', array(
'%plugin' => $implementation,
'%msg' => $e
->getMessage(),
));
\Drupal::logger('aes')
->error($error_msg);
return FALSE;
}
return $decrypted;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AES:: |
public static | function | Decrypts a string of encrypted data. | |
AES:: |
public static | function | Encrypts a string. | |
AES:: |
public static | function | Retrieve information about available AES implementations. | |
AES:: |
public static | function | Retrieve encryption key. Note we're using YAML files not DB settings. | |
AES:: |
public static | function | Load PHPSecLib files. | |
AES:: |
public static | function | Generate an IV - initialization vector - and store it in configuration. | |
AES:: |
public static | function | Generate a random key, containing uppercase, lowercase and digits. |