作者:燁竹
加密規(guī)則
絕不要以明文存儲(chǔ)密碼,永遠(yuǎn)使用 哈希算法 來(lái)處理密碼
-
絕不要使用 Base64 或其他編碼方式來(lái)存儲(chǔ)密碼秸谢,
這和以明文存儲(chǔ)密碼是一樣的凛澎,使用 哈希 ,而不要使用 編碼
編碼以及加密估蹄,都是雙向的過(guò)程塑煎,而密碼是保密的,應(yīng)該只被它的所有者知道元媚, 這個(gè)過(guò)程必須是單向的轧叽;哈希正是用于做這個(gè)的苗沧,從來(lái)沒(méi)有解哈希這種說(shuō)法, 但是編碼就存在解碼炭晒,加密就存在解密待逞;
-
絕不要使用弱哈希或已被破解的哈希算法网严,像 MD5 或 SHA1
這些算法太老了识樱,而且被證明存在缺陷,它們一開(kāi)始就并不是為了保存密碼而設(shè)計(jì)的震束,另外怜庸,絕不要自己發(fā)明算法
只使用強(qiáng)密碼哈希算法,例如 BCrypt 垢村,在 PHP 自己的 密碼哈希 函數(shù)中也是使用它
-
絕不要以明文形式顯示或發(fā)送密碼
即使是對(duì)密碼的所有者也應(yīng)該這樣割疾。如果你需要 "忘記密碼" 的功能,可以隨機(jī)生成一個(gè)新的 一次性的(這點(diǎn)很重要)密碼嘉栓,然后把這個(gè)密碼發(fā)送給用戶(hù)
-
絕不要對(duì)用戶(hù)的密碼做一些沒(méi)必要的限制
如果你使用除 BCrypt(它有最多 72 字符的限制)之外的其他哈希算法宏榕,你應(yīng)該設(shè)置一個(gè)相對(duì)長(zhǎng)一點(diǎn)的密碼長(zhǎng)度(例如 1024 字符),這樣可以緩解 DoS 攻擊
加密方式
MD5
$password = md5($_POST["password"]);
SHA256 和 SHA512
$password = hash("sha256", $password);
鹽值;;對(duì)侵佃,我們?cè)诩用艿臅r(shí)候其實(shí)會(huì)給加密的字符串添加一個(gè)額外的字符串麻昼,以達(dá)到提高一定安全的目的:
<?php
function generateHashWithSalt($password) {
$intermediateSalt = md5(uniqid(rand(), true));
$salt = substr($intermediateSalt, 0, 6);
return hash("sha256", $password . $salt);
}
Bcrypt;;Bcrypt 其實(shí)就是Blowfish和crypt()函數(shù)的結(jié)合,我們這里通過(guò)CRYPT_BLOWFISH判斷Blowfish是否可用馋辈,然后像上面一樣生成一個(gè)鹽值抚芦,不過(guò)這里需要注意的是,crypt()的鹽值必須以$2a$或者$2y$開(kāi)頭
資料:http://php.net/manual/en/function.crypt.php
<?php
function generateHash($password) {
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
$salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
return crypt($password, $salt);
}
}
Password Hashing API
password_hash() – 對(duì)密碼加密.
password_verify() – 驗(yàn)證已經(jīng)加密的密碼迈螟,檢驗(yàn)其hash字串是否一致.
password_needs_rehash() – 給密碼重新加密.
password_get_info() – 返回加密算法的名稱(chēng)和一些相關(guān)信息.
$hash = password_hash($passwod, PASSWORD_DEFAULT);
這里使用password_hash()你完全可以不提供鹽值(salt)和 消耗值 (cost)叉抡,你可以將后者理解為一種性能的消耗值,cost越大井联,加密算法越復(fù)雜卜壕,消耗的內(nèi)存也就越大。當(dāng)然烙常,如果你需要指定對(duì)應(yīng)的鹽值和消耗值,你可以這樣寫(xiě):
<?php
$options = [
'salt' => custom_function_for_salt(),
//write your own code to generate a suitable salt
'cost' => 12 // the default cost is 10
];
$hash = password_hash($password, PASSWORD_DEFAULT, $options);
密碼加密過(guò)后鹤盒,驗(yàn)證密碼是否正確:
<?php
if (password_verify($password, $hash)) {
// Pass
}
else {
// Invalid
}
更改加密方式蚕脏,更換鹽值或者提高消耗值
<?php
if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {
// cost change to 12
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// don't forget to store the new hash!
}
password_get_info()查看加密信息
algo – 算法實(shí)例
algoName – 算法名字
options – 加密時(shí)候的可選參數(shù)