public function getHashInfo($hash) { $passwordGetInfoResult = password_get_info($hash); $identifier = $passwordGetInfoResult[HashInfo::ALGORITHM_ID_KEY]; $name = $passwordGetInfoResult[HashInfo::ALGORITHM_NAME_KEY]; $options = $passwordGetInfoResult[HashInfo::OPTIONS_KEY]; return new HashInfo($identifier, $name, $options); }
public function update($params) { if (isset($params['password'])) { if (!password_get_info($params['password'])['algo']) { $params['password'] = password_hash($params['password'], PASSWORD_DEFAULT); } } return parent::update($params); }
public function password_hashing() { echo '<a href="http://www.codeigniter.com/user_guide/general/compatibility_functions.html">read</a>'; $hash = 'password_hash'; echo password_hash($hash, PASSWORD_DEFAULT); echo password_get_info($hash); echo password_needs_rehash($hash, PASSWORD_DEFAULT); echo password_verify('password_hash', $hash); }
/** * @param string $password * @param boolean $automateHash */ public function __construct($password, $automateHash = false) { $this->password = (string) $password; $info = password_get_info($this->password); $this->isHashed = 'unknown' !== $info['algoName']; if ($automateHash) { $this->hash(); } }
/** * @param string $hash * @return array */ public function getInfo($hash) { $clear = Helpers::getHash($hash); $signatureLength = $this->getSignatureLength(); $ivLength = $this->getIvLength(); if (!$this->verifySignature(Helpers::substr($clear, 0, $signatureLength), Helpers::substr($clear, $signatureLength))) { throw new \Ark8\Passwords\Exceptions\SignatureException('Signature does not match.'); } return password_get_info($this->decrypt(Helpers::substr($clear, $signatureLength, $ivLength), Helpers::substr($clear, $signatureLength + $ivLength))); }
/** * Constructor * * @param string $hash */ public function __construct($hash) { if (!is_string($hash)) { throw new DataType('hash', 'string', $hash); } $hashInfos = password_get_info($hash); if ($hashInfos['algo'] === 0) { throw new DataFormat('hash', 'a valid password hash', $hash); } $this->hash = $hash; }
public function saving($model) { foreach ($this->options['fields'] as $field) { $password = (string) $model[$field]; $info = password_get_info($password); if ($info['algo'] === 0) { // needs to be rehashed $model[$field] = password_hash($password, $this->options['algo'], $this->options['options']); } } }
public function setHash(string $hash) : PasswordInterface { if (empty($hash)) { throw new PasswordException('hash is empty'); } if (password_get_info($hash)['algo'] === 0) { throw new PasswordException('The hash is not understandable by the underlying library'); } $this->hashed = $hash; $this->isHashed = true; return $this; }
public function __construct($hashedPassword) { if (!is_string($hashedPassword) || empty($hashedPassword)) { throw new HashedPasswordException('The hashedPassword must be a non-empty string.'); } $info = password_get_info($hashedPassword); if (empty($info) || !isset($info['algo']) || empty($info['algo'])) { throw new HashedPasswordException('The given hashedPassword (' . $hashedPassword . ') is invalid.'); } $this->hashedPassword = $hashedPassword; $this->algo = $info['algo']; }
protected function canUpgradeInternalHash(PhutilOpaqueEnvelope $hash) { $info = password_get_info($hash->openEnvelope()); // NOTE: If the costs don't match -- even if the new cost is lower than // the old cost -- count this as an upgrade. This allows costs to be // adjusted down and hashing to be migrated toward the new cost if costs // are ever configured too high for some reason. $cost = idx($info['options'], 'cost'); if ($cost != $this->getBcryptCost()) { return true; } return false; }
/** * password_get_info() test * * Borrowed from PHP's own tests * * @depends test_bootstrap */ public function test_password_get_info() { $expected = array('algo' => 1, 'algoName' => 'bcrypt', 'options' => array('cost' => 10)); // default $this->assertEquals($expected, password_get_info('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y')); $expected['options']['cost'] = 11; // cost $this->assertEquals($expected, password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y')); $expected = array('algo' => 0, 'algoName' => 'unknown', 'options' => array()); // invalid length $this->assertEquals($expected, password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100')); // non-bcrypt $this->assertEquals($expected, password_get_info('$1$rasmusle$rISCgZzpwk3UhDidwXvin0')); }
public static function getType($hash) { $info = password_get_info($hash); if ($info['algo'] > 0) { return $info['algoName']; } if (substr($hash, 0, 3) == '$P$') { return 'phpass'; } if (preg_match('/^[A-Z0-9]{32}\\:[A-Z0-9]{2}$/i', $hash) === 1) { return 'salt'; } trigger_error('OSC\\OM\\Hash::getType() hash type not found for "' . substr($hash, 0, 5) . '"'); return ''; }
function password_needs_rehash($hash, $algorithm, $options = array()) { $info = password_get_info($hash); if ($info['algo'] != $algorithm) { return true; } switch ($algorithm) { case PASSWORD_BCRYPT: $cost = isset($options['cost']) ? $options['cost'] : 10; if ($cost != $info['options']['cost']) { return true; } break; } return false; }
public function verifyPassword($password) { if (!defined('PASSWORD_DEFAULT')) { require_once LIB_PATH . 'password_compat/password.php'; } $this->loggedIn = password_verify($password, $this->PasswordHash) === true; if ($this->loggedIn) { // Verify password hash algorithm and strength requirements. -- cwells $passwordInfo = password_get_info($this->PasswordHash); if (password_needs_rehash($this->PasswordHash, PASSWORD_DEFAULT, $passwordInfo['options']) === true || $passwordInfo['options']['cost'] !== self::HASH_COST) { // No need to verify success here since we'll try again on the next login. -- cwells $this->setPassword($password); } } return $this->loggedIn; }
/** * Get the password hash if it is plaintext. * If hashed password is passed, so just returns it. * * @param RecoveryAccess|string $password Password to hash. * * @return string */ public static function passwordHash($password) { if ($password instanceof RecoveryAccess) { $password = $password->password; } // Check password status. // It should detect if is a hashed password. $passwordStatus = password_get_info($password); if ($passwordStatus['algo'] === 0) { $hashOptions = []; // Overwrite the default cost. if (defined('VANILLA_RECOVERY_HASH_COST')) { $hashOptions['cost'] = VANILLA_RECOVERY_HASH_COST; } return (string) password_hash($password, PASSWORD_BCRYPT, $hashOptions); } return $password; }
/** * checks if the hashed password still meets our security requirements. false if rehash is needed * @param string $hash current hash * @return bool */ public static function checkPasswordSecurity($hash) { /* * PHP offers a password_needs_rehash() function, but it only checks if the values are the same. * e.g. having a different hashing cost for one password would result in rehashing and losing security * We check both relevant values ourselves and make sure we don't rehash unnecessarily */ // check if cost is too little $info = password_get_info($hash); if ($info['options']['cost'] < self::HASHING_COST) { return true; } // check if algo has changed if ($info['algo'] != self::HASHING_ALGO) { return true; } return false; }
public function fromDataToCredentials(array $data) { if (!isset($data['username'])) { throw new CredentialsException('The username keyname is mandatory in order to convert the data to a Credentials object.'); } if (!isset($data['password'])) { throw new CredentialsException('The password keyname is mandatory in order to convert the data to a Credentials object.'); } $password = null; $hashedPassword = null; $info = password_get_info($data['password']); if (!empty($info) && isset($info['algo']) && !empty($info['algo'])) { $hashedPassword = new ConcreteHashedPassword($data['password']); } if (empty($hashedPassword)) { $password = $data['password']; $hashedPassword = new ConcreteHashedPassword(password_hash($password, \PASSWORD_DEFAULT)); } return new ConcreteCredentials($data['username'], $hashedPassword, $password); }
public function checkPassword($password) { $passwordInfo = password_get_info($this->password); // Check for legacy unsalted SHA1 if (strlen($this->password) == 40 && $passwordInfo['algoName'] == "unknown") { if (hash("SHA1", $password) == $this->password) { $this->setPassword($password); TigerApp::log("Password for {$this->username} rehashed (Legacy)."); return true; } } if (password_verify($password, $this->password)) { // success. But check for needing to be rehashed. if (password_needs_rehash($this->password, PASSWORD_DEFAULT)) { $this->setPassword($password); $this->save(); TigerApp::log("Password for {$this->username} rehashed ({$passwordInfo['algoName']})."); } return true; } else { return false; } }
<?php var_dump(PASSWORD_DEFAULT == PASSWORD_BCRYPT); // true $password = '******'; // will be truncaged to 72 chars $hashed = password_hash($password, PASSWORD_DEFAULT); echo $hashed . PHP_EOL; var_dump(password_get_info($hashed)); var_dump(password_verify($password, $hashed)); echo PHP_EOL;
/** * Get information about the password hash. Returns an array of the information * that was used to generate the password hash. * * array( * 'algo' => 1, * 'algoName' => 'bcrypt', * 'options' => array( * 'cost' => 10, * ), * ) * * @param string $hash The password hash to extract info from * * @return array The array of information about the hash. */ public static function getInfos($hash) { return password_get_info($hash); }
/** * Check if a password needs a rehash. * @param string $hash The hash. * @return bool True if the password needs a rehash, false otherwise. */ public function needsRehash($hash) { if (!$this->_supportsBasicHash()) { return false; } $info = password_get_info($hash); if ($info['algo'] == 0) { return true; } return password_needs_rehash($hash, PASSWORD_DEFAULT); }
/** * Determine if the password hash needs to be rehashed according to the options provided * * If the answer is true, after validating the password using password_verify, rehash it. * * @param string $hash The hash to test * @param int $algo The algorithm used for new password hashes * @param array $options The options array passed to password_hash * * @return boolean True if the password needs to be rehashed. */ function password_needs_rehash($hash, $algo, array $options = array()) { $info = password_get_info($hash); if ($info['algo'] !== (int) $algo) { return true; } switch ($algo) { case PASSWORD_BCRYPT: $cost = isset($options['cost']) ? (int) $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST; if ($cost !== $info['options']['cost']) { return true; } break; } return false; }
/** * password_needs_rehash() * * @link http://php.net/password_needs_rehash * @param string $hash * @param int $algo * @param array $options * @return bool */ function password_needs_rehash($hash, $algo, array $options = array()) { $info = password_get_info($hash); if ($algo !== $info['algo']) { return TRUE; } elseif ($algo === 1) { $options['cost'] = isset($options['cost']) ? (int) $options['cost'] : 10; return $info['options']['cost'] !== $options['cost']; } // Odd at first glance, but according to a comment in PHP's own unit tests, // because it is an unknown algorithm - it's valid and therefore doesn't // need rehashing. return FALSE; }
/** * Returns information about a hashed password (algo, options, ...). * * Can be used to verify whether a string is compatible with password_hash(). * * @param string * @return array */ public function info($hash) { return password_get_info($hash); }
/** * Method to verify a password against a hash * * @param string $password * @param string $hash * @return boolean; */ protected function verify($password, $hash) { $info = password_get_info($hash); return $info['algo'] == 0 && $info['algoName'] == 'unknown' ? $password === $hash : password_verify($password, $hash); }
/** * Check is a password match the stored hash * * @since version 0.85 * * @param $pass string * @param $hash string * * @return boolean **/ static function checkPassword($pass, $hash) { $tmp = password_get_info($hash); if (isset($tmp['algo']) && $tmp['algo']) { $ok = password_verify($pass, $hash); } else { if (strlen($hash) == 32) { $ok = md5($pass) == $hash; } else { if (strlen($hash) == 40) { $ok = sha1($pass) == $hash; } else { $salt = substr($hash, 0, 8); $ok = $salt . sha1($salt . $pass) == $hash; } } } return $ok; }
/** * Determine if the password hash needs to be rehashed according to the options provided * * If the answer is true, after validating the password using password_verify, rehash it. * * @param string $hash The hash to test * @param int $algo The algorithm used for new password hashes * @param array $options The options array passed to password_hash * * @return boolean True if the password needs to be rehashed. */ public static function needs_rehash($hash, $algo = PASSWORD_BCRYPT, array $options = array()) { $info = password_get_info($hash); if ($info['algo'] != $algo) { return true; } switch ($algo) { case PASSWORD_BCRYPT: $cost = isset($options['cost']) ? $options['cost'] : 12; if ($cost != $info['options']['cost']) { return true; } break; } return false; }
/** * @dataProvider provideInfo */ public function testInfo($hash, $info) { $this->assertEquals($info, password_get_info($hash)); }
/** * @Validate(Password) * @DataType Password * @Last * @Embed */ function _validate_password(&$value, $args) { if (!password_get_info($value)['algo']) { $value = password_hash($value, PASSWORD_BCRYPT, ["cost" => 7, "salt" => sha1(implode(",", $args))]); } return true; }
</article> <article class="list init"> <h2>Function文件夹中的一些函数方法示例</h2> <p>各函数使用方法和说明详见:Function文件夹中的README.md介绍。</p> <p>运行结果:</p> <p>1、<code>password_hash</code>不指定盐值加密密码<code>zheshiyigemima123</code>输出结果:<code><?php var_dump(password_hash('zheshiyigemima123', PASSWORD_BCRYPT)); ?> </code>;没有通过第三个参数指定固定的盐值(系统会自己添加随机盐值),所以每刷新下结果都会变化的~~~</p> <p>2、<code>password_verify</code>效验密码<code>zheshiyigemima123</code>和曾经保存过的一个hash串<code>$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu</code>输出结果:<code><?php var_dump(password_verify('zheshiyigemima123', '$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu')); ?> </code></p> <p>3、<code>password_get_info</code>获取hash串<code>$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu</code>的信息,输出结果:<code><?php var_dump(password_get_info('$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu')); ?> </code></p> <p>4、<code>is_mail_valid</code>检测字符串<code>JJonline@JJonline.Cn</code>是否是一个合法的邮箱格式,输出:<code><?php var_dump(is_mail_valid('*****@*****.**')); ?> </code>;检测字符串<code>JJon-l#?ine@JJonline.Cn</code>是否是一个合法的邮箱格式,输出:<code><?php var_dump(is_mail_valid("JJon-l#?ine@JJonline.Cn")); ?> </code> <br>Ps1:其实按 RFC822标准<code>JJon-l#?ine@JJonline.Cn</code>是一个合法的邮箱地址,只不过如此反人类的邮箱地址果断不拽它 <br>Ps2:<code>is_mail_valid</code>默认采用正则检测,也可以采用<code>filter_var($mail,FILTER_VALIDATE_EMAIL)</code>方式支持RFC822标准 <br>Ps3:<code>is_mail_valid</code>检测邮箱格式的标准为:用户名部分构成仅能为数字、字母、下划线、加好、减号(中划线)和点,且开头位置仅能为数字或字母;域名部分按域名规则,支持域名中有减号(或者称之为中划线) <br> 测试支持检测的邮箱格式类型: <br> <code>is_mail_valid</code>检测邮箱地址字符串<code>JJonline-Cn@JJonline.Cn</code>的结果<code><?php var_dump(is_mail_valid('*****@*****.**'));