/** * Encrypt data returning a JSON encoded array safe for storage in a database * or file. The array has the following structure before it is encoded: * array( * 'cdata' => 'Encrypted data, Base 64 encoded', * 'iv' => 'Base64 encoded IV', * 'algo' => 'Algorythm used', * 'mode' => 'Mode used', * 'mac' => 'Message Authentication Code' * ) * * @param mixed $data * Data to encrypt. * * @param string $key * Key to encrypt data with. * * @return string * Serialized array containing the encrypted data along with some meta data. */ public function encrypt($data, $key) { /* Make sure both algorithm and mode are either block or non-block. */ $isBlockCipher = mcrypt_module_is_block_algorithm($this->_algo); $isBlockMode = mcrypt_module_is_block_algorithm_mode($this->_mode); if ($isBlockCipher !== $isBlockMode) { throw new \phpSec\Exception\InvalidAlgorithmParameterException('You can not mix block and non-block ciphers and modes'); return false; } $td = mcrypt_module_open($this->_algo, '', $this->_mode, ''); /* Check key size. */ $keySize = strlen($key); $keySizes = mcrypt_enc_get_supported_key_sizes($td); if (count($keySizes) > 0) { /* Encryption method requires a specific key size. */ if (!in_array($keySize, $keySizes)) { throw new \phpSec\Exception\InvalidKeySpecException('Key is out of range. Should be one of: ' . implode(', ', $keySizes)); return false; } } else { /* No specific size is needed. */ if ($keySize == 0 || $keySize > mcrypt_enc_get_key_size($td)) { throw new \phpSec\Exception\InvalidKeySpecException('Key is out of range. Should be between 1 and ' . mcrypt_enc_get_key_size($td) . ' bytes.'); return false; } } /* Using PBKDF with constant salts dedicated to each purpose * can securely derivce two keys from one */ $key1 = $this->pbkdf2($key, "encrypt", 1, $keySize); $key2 = $this->pbkdf2($key, "HMAC", 1, $keySize); /* Create IV. */ $rnd = $this->psl['crypt/rand']; $iv = $rnd->bytes(mcrypt_enc_get_iv_size($td)); /* Init mcrypt. */ mcrypt_generic_init($td, $key1, $iv); /* Prepeare the array with data. */ $serializedData = serialize($data); /* Enable padding of data if block cipher moode. */ if (mcrypt_module_is_block_algorithm_mode($this->_mode) === true) { $this->_padding = true; } /* Add padding if enabled. */ if ($this->_padding === true) { $block = mcrypt_enc_get_block_size($td); $serializedData = $this->pad($block, $serializedData); $encrypted['padding'] = 'PKCS7'; } $encrypted['algo'] = $this->_algo; /* Algorithm used to encrypt. */ $encrypted['mode'] = $this->_mode; /* Algorithm mode. */ $encrypted['iv'] = base64_encode($iv); /* Initialization vector, just a bunch of randomness. */ $encrypted['cdata'] = base64_encode(mcrypt_generic($td, $serializedData)); /* The encrypted data. */ $encrypted['mac'] = base64_encode($this->pbkdf2($encrypted['cdata'], $key2, 1, 32)); return json_encode($encrypted); }
/** * Encrypt data returning a JSON encoded array safe for storage in a database * or file. The array has the following structure before it is encoded: * array( * 'cdata' => 'Encrypted data, Base 64 encoded', * 'iv' => 'Base64 encoded IV', * 'algo' => 'Algorythm used', * 'mode' => 'Mode used', * 'mac' => 'Message Authentication Code' * ) * * @param mixed $data * Data to encrypt. * * @param string $key * Key to encrypt data with. * * @return string * Serialized array containing the encrypted data along with some meta data. */ public static function encrypt($data, $key) { $td = mcrypt_module_open(self::$_algo, '', self::$_mode, ''); /* Check key size. */ $keySize = strlen($key); $keySizes = mcrypt_enc_get_supported_key_sizes($td); if (count($keySizes) > 0) { /* Encryption method requires a specific key size. */ if (!in_array($keySize, $keySizes)) { phpsec::error('Key is out of range. Should be one of: ' . var_export($keySizes, 1)); return false; } } else { /* No spsecific size is needed. */ if ($keySize == 0 || $keySize > mcrypt_enc_get_key_size($td)) { phpsec::error('Key is out of range. Should be: 1 - ' . mcrypt_enc_get_key_size($td) . ' bytes.'); return false; } } /* Create IV. */ $iv = phpsecRand::bytes(mcrypt_enc_get_iv_size($td)); /* Init mcrypt. */ mcrypt_generic_init($td, $key, $iv); /* Prepeare the array with data. */ $serializedData = serialize($data); /* Add padding if enabled. */ if (self::$_padding === true) { $block = mcrypt_enc_get_block_size($td); $serializedData = self::pad($block, $serializedData); } $encrypted['algo'] = self::$_algo; /* Algorithm used to encrypt. */ $encrypted['mode'] = self::$_mode; /* Algorithm mode. */ $encrypted['iv'] = base64_encode($iv); /* Initialization vector, just a bunch of randomness. */ $encrypted['cdata'] = base64_encode(mcrypt_generic($td, $serializedData)); /* The encrypted data. */ $encrypted['mac'] = base64_encode(self::pbkdf2($encrypted['cdata'], $key, 1000, 32)); return json_encode($encrypted); }
/** * Initialises the cipher with the set key * * @param resource $cipher * @throws * @return resource */ protected function _initCipher($cipher) { $key = $this->_encryption['key']; $keysizes = mcrypt_enc_get_supported_key_sizes($cipher); if (empty($keysizes) || $this->_encryption['salt'] == true) { $this->_srand(); $keysize = mcrypt_enc_get_key_size($cipher); $key = substr(md5($key), 0, $keysize); } else { if (!in_array(strlen($key), $keysizes)) { #require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('The given key has a wrong size for the set algorithm'); } } $result = mcrypt_generic_init($cipher, $key, $this->_encryption['vector']); if ($result < 0) { #require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Mcrypt could not be initialize with the given setting'); } return $this; }
/** * Normalize key for PHP 5.6 for backwards compatibility * * This method is a shim to make PHP 5.6 behave in a B/C way for * legacy key padding when shorter-than-supported keys are used * * @param string $key encryption key * @param string $cipher mcrypt cipher * @param string $mode mcrypt mode */ protected function _normalize_key($key, $cipher, $mode) { // open the cipher $td = mcrypt_module_open($cipher, '', $mode, ''); // loop through the supported key sizes foreach (mcrypt_enc_get_supported_key_sizes($td) as $supported) { // if key is short, needs padding if (strlen($key) <= $supported) { return str_pad($key, $supported, ""); } } // at this point key must be greater than max supported size, shorten it return substr($key, 0, mcrypt_get_key_size($cipher, $mode)); }
<?php $td = mcrypt_module_open('rijndael-256', '', 'ecb', ''); $var = mcrypt_enc_get_supported_key_sizes($td); var_dump($var);
/** * Initialises the cipher with the set key * * @param resource $cipher * @throws * @return resource */ protected function _initCipher($cipher) { $key = $this->_encryption['key']; $keysizes = mcrypt_enc_get_supported_key_sizes($cipher); if (empty($keysizes) || ($this->_encryption['salt'] == true)) { $keysize = mcrypt_enc_get_key_size($cipher); $key = substr(md5($key), 0, $keysize); } else if (!in_array(strlen($key), $keysizes)) { throw new Exception\RuntimeException('The given key has a wrong size for the set algorithm'); } $result = mcrypt_generic_init($cipher, $key, $this->_encryption['vector']); if ($result < 0) { throw new Exception\RuntimeException('Mcrypt could not be initialize with the given setting'); } return $this; }
/** | @name | - logfrm_proc | | @params | - | | @return | - | | @description | - process new user profile | **/ function logfrm_proc() { global $g_SYSTEM_DATA; $this->etc->sec_logout(); //params log_message("INFO", "logfrm_proc() : start here"); $chiphername = mcrypt_enc_get_algorithms_name($cipher); $blocksize = mcrypt_enc_get_block_size($cipher); $mykeysize = mcrypt_enc_get_supported_key_sizes($cipher); log_message("INFO", "logfrm_proc() : {$chiphername}/{$blocksize} bytes "); foreach ($mykeysize as $value) { log_message("INFO", "logfrm_proc() : {$value} bytes "); } unset($value); //sess $dmp = @var_export($g_SYSTEM_DATA['_SESSION'], true); //get chk post $email = trim($this->input->post('email')); $pass = trim($this->input->post('pass')); $me = @intval(trim($this->input->post('me'))); //params log_message("INFO", "logfrm_proc() : info-params [ {$email} : {$pass} : {$me} ] {$dmp};"); //cancel? if (!$this->input->get_post('Login')) { //set status log_message("INFO", "logfrm_proc() : info [ NOT CLICKED ]"); //fwd redirect(site_url(DEFAULT_LOGGED_IN_PAGE)); return; } //exec $pdata = $this->etc->sec_login($email, $pass, $me); $dmp = @var_export($pdata, true); $by = $this->etc->get_name(); log_message("INFO", "logfrm_proc() : INFO-LOGIN [ {$dmp} ]"); if (!$pdata['status']) { //set status $smsg = intval($pdata['pdata']['data']->fieldtrial) >= intval($pdata['pdata']['data']->trial) ? $this->config->item('USER_LOGIN_ERROR_MAX') : $this->config->item('USER_LOGIN_ERROR'); $this->etc->set_error_message($smsg); log_message("INFO", "logfrm_proc() : INFO-LOGIN-ERR [ {$smsg} ]"); //fwd redirect(site_url(DEFAULT_LOGGED_IN_PAGE)); return; } //chk if its locked ??? if (intval($pdata['pdata']['data']->fieldtrial) >= intval($pdata['pdata']['data']->trial)) { //max reached $this->etc->set_error_message($this->config->item('USER_LOGIN_ERROR_MAX')); log_message("INFO", "logfrm_proc() : INFO-LOGIN-ERR [ LOCKED ]"); //fwd redirect(site_url(DEFAULT_LOGGED_IN_PAGE)); return; } //pass expired if (intval($pdata['pdata']['data']->expired) > 0) { //max reached $this->etc->set_error_message($this->config->item('USER_LOGIN_PASS_EXPIRED')); log_message("INFO", "logfrm_proc() : INFO-LOGIN-ERR [ PWD-EXPIRED ]"); //fwd redirect(site_url(DEFAULT_LOGGED_IN_PAGE)); return; } //in-active if (intval($pdata['pdata']['data']->flag_id) != 1) { //max reached $this->etc->set_error_message($this->config->item('USER_LOGIN_IN_ACTIVE')); log_message("INFO", "logfrm_proc() : INFO-LOGIN-ERR [ IN-ACTIVE ]"); //fwd redirect(site_url(DEFAULT_LOGGED_IN_PAGE)); return; } //flag_first=1, then fwd to change pass and NOT SUPER ROOT + can_change if (intval($pdata['pdata']['data']->flagfirst) == 1 && intval($pdata['pdata']['data']->can_change) == 1 && intval($pdata['pdata']['data']->usertype) != DEFAULT_USERTYPE_ROOT_ID) { /** //FLAGFIRST++ ( HOW MANY TIMES LOGGED IN) $this->secuser_model->set_column_ctr(array( 'id' => $pdata['pdata']['data']->user_id, 'by' => $by, 'col' => 'FLAGFIRST', 'val' => sprintf("%d",1+$pdata['pdata']['data']->flagfirst))); **/ log_message("INFO", "afrm_proc() : INFO-LOGIN [ FLAGFIRST=1 ]"); redirect(site_url('secuser/chpass')); return; } log_message("INFO", "afrm_proc() : login is GOOD [ goto admin ]"); //fwd redirect(site_url('admin')); return; }
/** * Validate encryption key based on valid key sizes for selected cipher and cipher mode * @param string $key Encryption key * @param resource $module Encryption module * @return void * @throws \InvalidArgumentException If key size is invalid for selected cipher */ protected function validateKeyLength($key, $module) { $keySize = strlen($key); $keySizeMin = 1; $keySizeMax = mcrypt_enc_get_key_size($module); $validKeySizes = mcrypt_enc_get_supported_key_sizes($module); if ($validKeySizes) { if (!in_array($keySize, $validKeySizes)) { throw new \InvalidArgumentException('Encryption key length must be one of: ' . implode(', ', $validKeySizes)); } } else { if ($keySize < $keySizeMin || $keySize > $keySizeMax) { throw new \InvalidArgumentException(sprintf('Encryption key length must be between %s and %s, inclusive', $keySizeMin, $keySizeMax)); } } }
$CC = "4007000000027"; $encrypted = mcrypt_ofb(MCRYPT_RIJNDAEL_128, substr($key, 0, 32), $CC, MCRYPT_ENCRYPT, substr($key, 32, 16)); $decrypted = mcrypt_ofb(MCRYPT_RIJNDAEL_128, substr($key, 0, 32), $encrypted, MCRYPT_DECRYPT, substr($key, 32, 16)); VERIFY($encrypted !== $decrypted); VS($decrypted, $CC); ////////////////////////////////////////////////////////////////////// VS(mcrypt_get_block_size("tripledes", "ecb"), 8); VS(mcrypt_get_cipher_name(MCRYPT_TRIPLEDES), "3DES"); VS(mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB), 16); VS(mcrypt_get_iv_size("des", "ecb"), 8); VS(mcrypt_get_key_size("tripledes", "ecb"), 24); $td = mcrypt_module_open("cast-256", "", "cfb", ""); VS(mcrypt_enc_get_algorithms_name($td), "CAST-256"); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_get_block_size($td), 8); $td = mcrypt_module_open("cast-256", "", "cfb", ""); VS(mcrypt_enc_get_iv_size($td), 16); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_get_key_size($td), 24); $td = mcrypt_module_open("cast-256", "", "cfb", ""); VS(mcrypt_enc_get_modes_name($td), "CFB"); $td = mcrypt_module_open("rijndael-256", "", "ecb", ""); VS(mcrypt_enc_get_supported_key_sizes($td), array(16, 24, 32)); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_is_block_algorithm_mode($td), true); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_is_block_algorithm($td), true); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_is_block_mode($td), true); $td = mcrypt_module_open("tripledes", "", "ecb", ""); VS(mcrypt_enc_self_test($td), 0);
<?php $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, ''); mcrypt_generic_init($td, '', 'a'); var_dump(mcrypt_enc_get_algorithms_name($td)); var_dump(mcrypt_enc_get_block_size($td)); var_dump(mcrypt_enc_get_iv_size($td)); var_dump(mcrypt_enc_get_key_size($td)); var_dump(mcrypt_enc_get_modes_name($td)); var_dump(mcrypt_enc_get_supported_key_sizes($td)); var_dump(mcrypt_enc_self_test($td)); var_dump(mcrypt_generic_init($td, '', 'a'));
/** * Returns supported key lengths for given cipher and mode. * * @return mixed array of discrete supported key lengths or integer with maximum key key length */ public function getSupportedKeyLengths() { $supportedKeyLengths = array(); $ed = @mcrypt_module_open($this->currentCipher ? $this->currentCipher : $this->defaultCipher, $this->cipherDir ? $this->cipherDir : ini_get('mcrypt.algorithms_dir'), $this->currentMode ? $this->currentMode : $this->defaultMode, $this->modeDir ? $this->modeDir : ini_get('mcrypt.modes_dir')); if ($ed !== false) { $supportedKeyLengths = mcrypt_enc_get_supported_key_sizes($ed); if (empty($supportedKeyLengths)) { $supportedKeyLengths = mcrypt_enc_get_key_size($ed); } } return $supportedKeyLengths; }
/** * Create binary key of length compatible to * mcrypt_enc_get_supported_key_sizes() from text string of arbitrary * length using kdf() method. * * @param string $src_key Text representation of cypher key. * @return string Binary key. It will be always the same length or a * bit more as $src_key. */ protected function keyPrepare($src_key) { //default key length is source key length $key_length = strlen($src_key); //choose one of algorithm supperted sizes $key_sizes = mcrypt_enc_get_supported_key_sizes($this->cypher); if (sizeof($key_sizes) > 0) { //sort array of supported key sizes as we shouldn/t guess if it //is sorted or not sort($key_sizes); //find first key size that will be equal or greater than //$src_key for ($i = 0, $found = false; $i < sizeof($key_sizes) && !$found; $i++) { //key length we need if ($key_sizes[$i] >= $key_length) { $key_length = $key_sizes[$i]; $found = true; } } } //key is bigger than maximum if ($key_length > mcrypt_enc_get_key_size($this->cypher)) { $key_length = mcrypt_enc_get_key_size($this->cypher); } $key = $this->kdf($this->KDF_algo, $src_key, $this->KDF_salt, $key_length); return $key; }