Current Path : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/main/lib/security/ |
Current File : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/main/lib/security/cipher.php |
<?php /** * Bitrix Framework * @package bitrix * @subpackage main * @copyright 2001-2018 Bitrix */ namespace Bitrix\Main\Security; class Cipher { protected $cipherAlgorithm; protected $hashAlgorithm; protected $ivLength; protected $calculateHash; /** * Cipher constructor. Aes-256-ctr and sha256 are the best currently known methods. * @param string $cipherAlgorithm * @param string $hashAlgorithm * @param bool $calculateHash * @throws SecurityException */ public function __construct($cipherAlgorithm = 'aes-256-ctr', $hashAlgorithm = 'sha256', $calculateHash = true) { if(!function_exists('openssl_get_cipher_methods')) { throw new SecurityException("Openssl extension is not available."); } if(!in_array($cipherAlgorithm, openssl_get_cipher_methods(true))) { throw new SecurityException("Unknown cipher algorithm {$cipherAlgorithm}."); } if(!in_array($hashAlgorithm, openssl_get_md_methods(true))) { throw new SecurityException("Unknown hash algorithm {$hashAlgorithm}."); } $this->cipherAlgorithm = $cipherAlgorithm; $this->hashAlgorithm = $hashAlgorithm; $this->ivLength = openssl_cipher_iv_length($cipherAlgorithm); $this->calculateHash = (bool)$calculateHash; } /** * Encrypts the data by key (symmetric cipher). * @param string $data * @param string $key * @return string Base64 encoded. * @throws SecurityException */ public function encrypt($data, $key) { // Initialisation vector: it MUST be different every time $iv = openssl_random_pseudo_bytes($this->ivLength, $strong); if(!$strong) { throw new SecurityException("Not a strong initialisation vector."); } // Hash the key: we shouldn't use the password itself, it can be weak $keyHash = openssl_digest($iv.$key, $this->hashAlgorithm, true); if($this->calculateHash) { //store the hash to check on reading $dataHash = openssl_digest($data, $this->hashAlgorithm, true); $data = $dataHash.$data; } // Encrypt the data $encrypted = openssl_encrypt($data, $this->cipherAlgorithm, $keyHash, OPENSSL_RAW_DATA, $iv); if($encrypted === false) { throw new SecurityException("Encryption failed: ".openssl_error_string()); } // Store IV with encrypted data to use it for decryption $res = $iv.$encrypted; return $res; } /** * Decrypts the data by key (symmetric cipher). * @param string $data Base64 encoded * @param string $key * @return string * @throws SecurityException */ public function decrypt($data, $key) { // Extract the initialisation vector and encrypted data $iv = substr($data, 0, $this->ivLength); $raw = substr($data, $this->ivLength); // Hash the key $keyHash = openssl_digest($iv.$key, $this->hashAlgorithm, true); // Decrypt $result = openssl_decrypt($raw, $this->cipherAlgorithm, $keyHash, OPENSSL_RAW_DATA, $iv); if($result === false) { throw new SecurityException("Decryption failed: ".openssl_error_string()); } if($this->calculateHash) { //extract the hash and decrypted data $length = strlen($keyHash); $hash = substr($result, 0, $length); $result = substr($result, $length); //check the hash: may be the crypto key has changed? It shouldn't. $dataHash = openssl_digest($result, $this->hashAlgorithm, true); if($dataHash !== $hash) { throw new SecurityException("The hash is incorrect: the data was corrupted or a wrong key was supplied."); } } return $result; } }