. // Encryption methods class Crypto extends Secrets { protected $prefix; protected $cost = '$10$'; protected $encryptionHash; protected $ivSize; protected $cipher = 'aes-128-cbc'; protected $options; protected $alphabet = 'aAbBcCdDeEfFgGhHiIjJkKlLmM.nNoOpPqQrRsStTuUvVwWxXyYzZ/0123456789'; public function __construct () { // Throw exception if encryption key isn't at least 8 characters long if (mb_strlen ($this->encryptionKey, '8bit') < 8) { throw new \Exception ( 'Encryption key must by at least 8 characters long.' ); } // Blowfish prefix $this->prefix = (version_compare (PHP_VERSION, '5.3.7') < 0) ? '$2a' : '$2y'; // OpenSSL raw output/options $this->options = defined ('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : true; // SHA-256 hash array $this->encryptionHash = str_split (hash ('sha256', $this->encryptionKey)); // OpenSSL cipher IV $this->ivSize = openssl_cipher_iv_length ($this->cipher); } // Creates Blowfish hash for passwords public function createHash ($string) { // Alphanumeric character array $alphabet = str_split ($this->alphabet); // Shuffle alphanumeric character array as to randomize it shuffle ($alphabet); // Initial salt $salt = ''; // Generate random 20 character alphanumeric string foreach (array_rand ($alphabet, 20) as $character) { $salt .= $alphabet[$character]; } // Blowfish hash $hash = crypt ($string, $this->prefix . $this->cost . $salt . '$$'); // Return hashed string return $hash; } // Creates Blowfish hash with salt from supplied hash public function verifyHash ($string, $compare) { // Split string by dollar sign $parts = explode ('$', $compare); // Hash salt $salt = !empty ($parts[3]) ? $parts[3] : ''; // Encryption string as Blowfish hash $hash = crypt ($string, $this->prefix . $this->cost . $salt . '$$'); // Returns true if both match return ($hash === $compare); } // Generates a random encryption key protected function createKey ($string) { // Shuffle alphanumeric character array as to randomize it shuffle ($string); // Initial array keys $keys = array (); // Initial key $encryption_key = ''; // Generate random string from encryption key SHA-256 hash for ($k = 0; $k < 16; $k++) { // Add encryption key character index to keys array $keys[] = array_search ($string[$k], $this->encryptionHash); // Add encryption key character to key $encryption_key .= $string[$k]; } // Convert encryption hash array keys to string $list = join (',', $keys); // Return encryption key info return array ( // Randomly generated encryption key 'key' => $encryption_key, // List of encryption hash array keys 'keys' => $list ); } // OpenSSL encrypt with random key from SHA-256 hash for e-mails public function encrypt ($string) { // Get a random encryption key $key_pair = $this->createKey ($this->encryptionHash); // Get pseudo-random bytes for OpenSSL IV $iv = openssl_random_pseudo_bytes ($this->ivSize); // OpenSSL encrypt using random encryption key $encrypted = openssl_encrypt ( // String being encrypted $string, // Encryption cipher method $this->cipher, // Generated encryption key $key_pair['key'], // OpenSSL options $this->options, // Initialization vector $iv ); // Encode encrypted text as base64 $encoded = base64_encode ($iv . $encrypted); // Return encryption info return array ( // Encrypted string 'encrypted' => $encoded, // List of encryption hash array keys 'keys' => $key_pair['keys'] ); } // Decrypt OpenSSL encrypted string public function decrypt ($string, $keys) { // Return false if string or keys is empty if (empty ($string) or empty ($keys)) { return false; } // Initial key $decryption_key = ''; // Split keys string into array $keys = explode (',', $keys); // Retrieve random key from array foreach ($keys as $value) { // Cast key to integer $hash_key = (int)($value); // Check if encryption hash key exists if (isset ($this->encryptionHash[$hash_key])) { // If so, add character to decryption key $decryption_key .= $this->encryptionHash[$hash_key]; } else { // If not, give up and return false return false; } } // Decode base64 encoded string $decoded = base64_decode ($string, true); // Get length of decoded string $length = mb_strlen ($decoded, '8bit'); // Get decipher text from decoded string $decrypted = mb_substr ($decoded, $this->ivSize, $length, '8bit'); // Setup OpenSSL IV $iv = mb_substr ($decoded, 0, $this->ivSize, '8bit'); // Return OpenSSL decrypted string return openssl_decrypt ( // String being decrypted $decrypted, // Encryption decipher method $this->cipher, // Retrieved decryption key $decryption_key, // OpenSSL options $this->options, // Initialization vector $iv ); } }