中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在PHP中實現一個密碼散列算法

發布時間:2021-06-07 18:07:04 來源:億速云 閱讀:134 作者:Leah 欄目:編程語言

這期內容當中小編將會給大家帶來有關怎么在PHP中實現一個密碼散列算法,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

查看密碼散列函數的加密算法

首先,我們還是看看當前環境中所支持的 password_hash() 算法。

print_r(password_algos());
// Array
// (
//     [0] => 2y
// )

可以看出,當前環境中,我們只有 2y 這一種算法可以使用,這個函數是 PHP7.4 才提供的。我們簡單的了解一下即可。

使用密碼散列函數加密數據

重點還是在這個加密函數的應用上,我們就來看看 password_hash() 這個函數的使用。這個函數是在 PHP5.5 之后就已經提供了,大家可以放心地使用。

echo password_hash("this is password", PASSWORD_DEFAULT), PHP_EOL;
// $2y$10$vOI56sADJPhebhzq5Bj1quM7grMex3Y4NlI99C3qP83iveEGnfdd.

echo password_hash("this is password", PASSWORD_DEFAULT), PHP_EOL;
// $2y$10$YMq8zsTw32HCOeWmlLSpruWKiSoO/rlNu2OVcIV4hlVSY4enn8GwS

沒錯,就是這么地簡單,PASSWORD_DEFAULT 是我們指定的加密算法,這里我們給的就是一個默認值。然而加密出來的數據并不是像 md5() 之類的是一個 16進制 字符串呀。是的,password_hash() 加密出來的內容并不是 md5 類型的 Hash 串,而是類似于像 JWT 一樣的一套加密字符串。

關于 JWT 的內容大家可以自行了解一下,在這里,最主要的就是 password_hash() 加密出來的內容和 JWT 一樣,在加密串的里面是包含一些信息的,比如加密循環次數和鹽值信息。這些信息是后面我們進行密碼匹配時所必須的內容。

有人又說了,既然有鹽值,為什么我們沒有定義這個鹽值呀,這樣我們后面如何匹配呢?就像前面說的那樣,這個加密后的字符串本身已經包含了鹽值信息,而且這個鹽值信息是系統隨機生成的,只能使用對應的比較函數才能比較原始明文密碼和加密后的密碼是否一致,這樣就能讓系統的安全性提高很多。

請注意上面的測試代碼,我們兩段代碼的明文是一樣的,但是加密出來的密碼散列可是完全不相同的哦。當然,更重要的是,這個加密后的密碼也是不可反解碼的,是一個正規的單向 Hash 散列。所以它是非常安全的一個密碼加密函數,這也是官方推薦它的原因。

那么,我們可以指定它的鹽值嗎?當然可以。

$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options), PHP_EOL;
// $2y$12$YjEdiCJHAmPCoidNvgrZq.k4VH3ShoELWlyU9POHD5sV3L1WW4.vS

$options = [
    'cost' => 11,
    'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
// $2y$11$syLcOhq1Mfc32cWVi1zyLOvSn.AtcCre.kY999uUXZ6pS3nXNv1lmPHP

最后一個參數是一個選項數組,在這個選項數組中,cost 代表加密循環次數(循環加密多少次),salt 當然就是我們的鹽值了,這里使用的是 mcrypt_create_iv() 生成的,我們也可以使用自己生成的隨機字符串來當做 salt 使用。

不過,劃重點了,在 PHP7 以后,選項參數數組中的 salt 已經是被標記成過時廢棄狀態了。如果使用這個的話,會報出 deprecated 警告。也就是說,官方期望我們還是不要使用自定義的 salt 來進行加密,而是使用默認情況下的由系統自動隨機生成的 salt 。

所以,我們在日常使用中,直接使用第一行代碼那種形式進行加密就可以了,有特殊需要的話,可以指定 cost 來改變循環次數,不同的循環次數要根據當前系統的硬件來定,當然越高對于系統來說也需要更高的硬件支持,默認情況下,這個值是 10 。

查看加密字符串的信息

$p = password_hash('this is password', PASSWORD_DEFAULT, $options);

print_r(password_get_info($p));
// Array
// (
//     [algo] => 2y
//     [algoName] => bcrypt
//     [options] => Array
//         (
//             [cost] => 11
//         )

// )

很簡單的一個函數,就是可以幫助我們看到這個加密數據的加密信息,就簡單的說下返回的信息內容吧。algo 就是使用的加密算法,前面我們已經看過當前系統中只有 2y 這一種算法,所以我們使用的 PASSWORD_DEFAULT 這個默認算法也就只能是它了。algoName 就是算法的可讀名稱,我們的算法正式名稱就是 bcrypt 算法。options 數組里面其實就是我們給定的選項參數內容。從這個函數就可以看出來,算法的信息真的是包含在了加密后的字符串中。

驗證密碼散列數據格式是否一致

有的時候,我們想要升級當前的密碼強度,比如將密碼循環次數增加,而數據庫中新老算法的密碼混雜著記錄在一起,這時應該怎么辦呢?

var_dump(password_needs_rehash($p, PASSWORD_DEFAULT, $options)); // bool(false)
var_dump(password_needs_rehash($p, PASSWORD_DEFAULT, ['cost'=>5])); // bool(true)

password_needs_rehash() 是 PHP 提供給我們的用于比對當前加密串的內容是否和我們所提供的算法和選項一致,如果是一致的返回的是 false ,如果不一致,返回的是 true 。額,這個又有點繞了,不是應該一致返回的是 true 嗎?

其實從函數的名字就可以看出來,這個函數的意思是 密碼(password) 是否需要(needs) 重新Hash(rehash) 。也就是說,如果算法和選項一致的話,那么這個密碼是不需要重新 Hash 的,當然返回的就是 false 啦,而算法或選項有不一致的地方的話,這個密碼就是需要重新 Hash 的,返回的就是 true 了。大家一定不要用反了。

驗證密碼

最后,也是最重要的,我們要驗證明文密碼和加密密碼是否一致的時候應該怎么辦呢?如果是原來的 md5 方式,我們將明文密碼也進行相同的加密之后再用雙等號進行比較就可以了。但是 password_hash() 這種就不行了,因為它的 salt 是隨機的,也不需要我們去保存,所以即使是相同的字符串,我們也不能保證每次加密的結果是一樣的,那么就要使用系統為我們提供的驗證函數了。

var_dump(password_verify('this is password', $p)); // bool(true)

var_dump(password_verify('1this is password', $p)); // bool(false)

上述就是小編為大家分享的怎么在PHP中實現一個密碼散列算法了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

随州市| 确山县| 盖州市| 淮阳县| 恩施市| 开原市| 锦屏县| 建湖县| 福泉市| 科技| 清丰县| 本溪市| 遂平县| 五家渠市| 泗阳县| 新化县| 理塘县| 平昌县| 石台县| 丹棱县| 拉萨市| 拉孜县| 旬阳县| 中西区| 乌拉特前旗| 秦皇岛市| 葫芦岛市| 安西县| 乌拉特后旗| 宿州市| 青龙| 榆林市| 饶平县| 莱西市| 卓资县| 武功县| 平和县| 鞍山市| 永顺县| 房山区| 兴仁县|