diff --git a/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php b/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php index b49d0c2d1..396eb86a7 100644 --- a/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php +++ b/sources/Application/SimpleCrypt/SimpleCryptOpenSSLMcryptCompatibilityEngine.php @@ -1,379 +1,4 @@ - -/** - * SimpleCrypt Class - crypto helpers - * Simple encryption of strings, uses mcrypt or degrades to a pure PHP - * implementation when mcrypt is not present. - * Based on Miguel Ros' work found at: - * http://rossoft.wordpress.com/2006/05/22/simple-encryption-class/ - * - * Usage: - * $oSimpleCrypt = new SimpleCrypt(); - * $encrypted = $oSimpleCrypt->encrypt('a_key','the_text'); - * $sClearText = $oSimpleCrypt->decrypt('a_key',$encrypted); - * - * The result is $plain equals to 'the_text' - * - * You can use a different engine if you don't have Mcrypt: - * $oSimpleCrypt = new SimpleCrypt('Simple'); - * - * A string encrypted with one engine can't be decrypted with - * a different one even if the key is the same. - * - * @author Miguel Ros - * @copyright Copyright (C) 2010-2024 Combodo SAS - * @license http://opensource.org/licenses/AGPL-3.0 - */ - -class SimpleCrypt -{ - /** - * @var \SimpleCrypt - * @since 3.1.0 N°5388 - */ - protected $oEngine; - - public static function GetNewDefaultParams() - { - if(function_exists('sodium_crypto_secretbox_open') && function_exists('random_bytes')){ - $sEngineName = 'Sodium'; - } - else if (function_exists('openssl_decrypt')) - { - $sEngineName = 'OpenSSL'; - } - else if(function_exists('mcrypt_module_open')){ - $sEngineName = 'Mcrypt'; - } - else - { - $sEngineName = 'Simple'; - } - $sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine'; - return $sEngineName::GetNewDefaultParams(); - } - - /** - * Constructor - * @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt, Sodium or OpenSSL - * @throws Exception This library is unkown - */ - function __construct($sEngineName = 'Mcrypt') - { - switch($sEngineName){ - case 'Sodium': - if(!function_exists('sodium_crypto_secretbox_open')){ - $sEngineName = 'Simple'; - } - break; - case 'Mcrypt': - if(!function_exists('mcrypt_module_open')){ - if (function_exists('openssl_decrypt')) - { - $sEngineName = 'OpenSSLMcryptCompatibility'; - } - else - { - $sEngineName = 'Simple'; - } - } - break; - case 'OpenSSL': - case 'OpenSSLMcryptCompatibility': - if(!function_exists('openssl_decrypt')){ - $sEngineName = 'Simple'; - } - break; - case 'Simple': - break; - default: - throw new Exception(Dict::Format("Core:AttributeEncryptUnknownLibrary", $sEngineName)); - } - - $sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine'; - $this->oEngine = new $sEngineName; - } - - /** - * Encrypts the string with the given key - * @param string $key - * @param string $sString Plaintext string - * @return string Ciphered string - */ - function Encrypt($key, $sString) - { - return $this->oEngine->Encrypt($key,$sString); - } - - - /** - * Decrypts the string by the given key - * @param string $key - * @param string $string Ciphered string - * @return string Plaintext string - */ - function Decrypt($key, $string) - { - return $this->oEngine->Decrypt($key,$string); - } - - /** - * Returns a random "salt" value, to be used when "hashing" a password - * using a one-way encryption algorithm, to prevent an attack using a "rainbow table" - * Tryes to use the best available random number generator - * @return string The generated random "salt" - */ - static function GetNewSalt() - { - // Copied from http://www.php.net/manual/en/function.mt-rand.php#83655 - // get 128 pseudorandom bits in a string of 16 bytes - - $sRandomBits = null; - - // Unix/Linux platform? - $fp = @fopen('/dev/urandom','rb'); - if ($fp !== FALSE) - { - //echo "Random bits pulled from /dev/urandom
\n"; - $sRandomBits .= @fread($fp,16); - @fclose($fp); - } - else - { - // MS-Windows platform? - if (@class_exists('COM')) - { - // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx - try - { - $CAPI_Util = new COM('CAPICOM.Utilities.1'); - $sBase64RandomBits = ''.$CAPI_Util->GetRandom(16,0); - - // if we ask for binary data PHP munges it, so we - // request base64 return value. We squeeze out the - // redundancy and useless ==CRLF by hashing... - if ($sBase64RandomBits) - { - //echo "Random bits got from CAPICOM.Utilities.1
\n"; - $sRandomBits = md5($sBase64RandomBits, TRUE); - } - } - catch (Exception $ex) - { - // echo 'Exception: ' . $ex->getMessage(); - } - } - } - if ($sRandomBits == null) - { - // No "strong" random generator available, use PHP's built-in mechanism - //echo "Random bits generated from mt_rand
\n"; - mt_srand(crc32(microtime())); - $sRandomBits = ''; - for($i = 0; $i < 4; $i++) - { - $sRandomBits .= sprintf('%04x', mt_rand(0, 65535)); - } - - - } - return $sRandomBits; - } -} - -/** - * Interface for encryption engines - */ -interface CryptEngine -{ - public static function GetNewDefaultParams(); - function Encrypt($key, $sString); - function Decrypt($key, $encrypted_data); -} - -/** - * Simple Engine doesn't need any PHP extension. - * Every encryption of the same string with the same key - * will return the same encrypted string - */ -class SimpleCryptSimpleEngine implements CryptEngine -{ - public static function GetNewDefaultParams() - { - return array( 'lib' => 'Simple', 'key' => null); - } - - public function Encrypt($key, $sString) - { - $result = ''; - for($i=1; $i<=strlen($sString); $i++) - { - $char = substr($sString, $i-1, 1); - $keychar = substr($key, ($i % strlen($key))-1, 1); - $char = chr(ord($char)+ord($keychar)); - $result.=$char; - } - return $result; - } - - public function Decrypt($key, $encrypted_data) - { - $result = ''; - for($i=1; $i<=strlen($encrypted_data); $i++) - { - $char = substr($encrypted_data, $i-1, 1); - $keychar = substr($key, ($i % strlen($key))-1, 1); - $char = chr(ord($char)-ord($keychar)); - $result.=$char; - } - return $result; - } -} - -/** - * McryptEngine requires Mcrypt extension - * Every encryption of the same string with the same key - * will return a different encrypted string. - */ -class SimpleCryptMcryptEngine implements CryptEngine -{ - var $alg = MCRYPT_BLOWFISH; - var $td = null; - - public static function GetNewDefaultParams() - { - return array('lib' => 'Mcrypt', 'key' => null); - } - - - public function __construct() - { - $this->td = mcrypt_module_open($this->alg,'','cbc',''); - } - - public function Encrypt($key, $sString) - { - $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_DEV_URANDOM); // MCRYPT_DEV_URANDOM is now useable since itop requires php >= 5.6 - if (false === $iv) { - throw new Exception('IV generation failed'); - } - mcrypt_generic_init($this->td, $key, $iv); - if (empty($sString)) - { - $sString = str_repeat("\0", 8); - } - $encrypted_data = mcrypt_generic($this->td, $sString); - mcrypt_generic_deinit($this->td); - return $iv.$encrypted_data; - } - - public function Decrypt($key, $encrypted_data) - { - $iv = substr($encrypted_data, 0, mcrypt_enc_get_iv_size($this->td)); - $string = substr($encrypted_data, mcrypt_enc_get_iv_size($this->td)); - $r = mcrypt_generic_init($this->td, $key, $iv); - if (($r < 0) || ($r === false)) - { - $decrypted_data = Dict::S("Core:AttributeEncryptFailedToDecrypt"); - } - else - { - $decrypted_data = rtrim(mdecrypt_generic($this->td, $string), "\0"); - mcrypt_generic_deinit($this->td); - } - return $decrypted_data; - } - - public function __destruct() - { - mcrypt_module_close($this->td); - } -} -/** -* SodiumEngine requires Sodium extension -* Every encryption of the same string with the same key -* will return a different encrypted string. - * The key has to be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long. - */ -class SimpleCryptSodiumEngine implements CryptEngine -{ - public static function GetNewDefaultParams() - { - return array('lib' => 'Sodium', 'key' => bin2hex(sodium_crypto_secretbox_keygen())); - } - - public function Encrypt($key, $sString) - { - $key = hex2bin($key); - $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); - $encrypted_string = sodium_crypto_secretbox($sString, $nonce, $key); - sodium_memzero($sString); - sodium_memzero($key); - return base64_encode($nonce.$encrypted_string); - } - - public function Decrypt($key, $encrypted_data) - { - $key = hex2bin($key); - $encrypted_data = base64_decode($encrypted_data); - $nonce = mb_substr($encrypted_data, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit'); - $encrypted_data = mb_substr($encrypted_data, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit'); - $plaintext = sodium_crypto_secretbox_open($encrypted_data, $nonce, $key); - if ($plaintext === false) - { - $plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt"); - } - sodium_memzero($encrypted_data); - sodium_memzero($key); - return $plaintext; - } - -} -class SimpleCryptOpenSSLEngine implements CryptEngine -{ - public static function GetNewDefaultParams() - { - return array('lib' => 'OpenSSL', 'key' => bin2hex(openssl_random_pseudo_bytes(32))); - } - - public function Encrypt($key, $sString) - { - $key = hex2bin($key); - $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC")); - $encrypted_string = openssl_encrypt($sString, "AES-256-CBC", $key, 0 , $iv); - return $iv.$encrypted_string; - } - - public function Decrypt($key, $encrypted_data) - { - $key = hex2bin($key); - $iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("AES-256-CBC"), '8bit'); - $encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("AES-256-CBC"), null, '8bit'); - $plaintext = openssl_decrypt($encrypted_data,"AES-256-CBC", $key, 0 , $iv); - if ($plaintext === false) - { - $plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt"); - } - return trim($plaintext); - } - -} class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine { @@ -381,31 +6,33 @@ class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine { return array('lib' => 'OpenSSLMcryptCompatibility', 'key' => null); } + //fix for php < 7.1.8 (keys are Zero padded instead of cycle padded) static private function MakeOpenSSLBlowfishKey($key) { - if("$key" === '') - { + if ("$key" === '') { return $key; } - $len = (16+2)*4; - while(strlen($key) < $len) - { + $len = (16 + 2) * 4; + while (strlen($key) < $len) { $key .= $key; } $key = substr($key, 0, $len); + return $key; } + public function Encrypt($key, $sString) { $key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key); $blockSize = 8; $len = strlen($sString); - $paddingLen = intval (($len + $blockSize -1) / $blockSize) * $blockSize - $len; + $paddingLen = intval(($len + $blockSize - 1) / $blockSize) * $blockSize - $len; $padding = str_repeat("\0", $paddingLen); - $sData = $sString . $padding; + $sData = $sString.$padding; $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("BF-CBC")); $encrypted_string = openssl_encrypt($sData, "BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + return $iv.$encrypted_string; } @@ -414,12 +41,12 @@ class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine $key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key); $iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("BF-CBC"), '8bit'); $encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("BF-CBC"), null, '8bit'); - $plaintext = openssl_decrypt($encrypted_data,"BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - if ($plaintext === false) - { + $plaintext = openssl_decrypt($encrypted_data, "BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + if ($plaintext === false) { $plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt"); } + return trim($plaintext); } -} +} \ No newline at end of file