成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

密碼存儲(chǔ)中MD5的安全問題與替代方案

gnehc / 1032人閱讀

首發(fā)地址:我的個(gè)人博客,轉(zhuǎn)載請注明出處。

md5安全嗎?

經(jīng)過各種安全事件后,很多系統(tǒng)在存放密碼的時(shí)候不會(huì)直接存放明文密碼了,大都改成了存放了 md5 加密(hash)后的密碼,可是這樣真的安全嗎?

這兒有個(gè)腳本來測試下MD5的速度, 測試結(jié)果:

[root@f4d5945f1d7c tools]# php speed-of-md5.php
Array
(
    [rounds] => 100
    [times of a round] => 1000000
    [avg] => 0.23415904045105
    [max] => 0.28906106948853
    [min] => 0.21188998222351
)

有沒有發(fā)現(xiàn)一個(gè)問題:MD5速度太快了,導(dǎo)致很容易進(jìn)行暴力破解.

簡單計(jì)算一下:

> Math.pow(10, 6) / 1000000 * 0.234
0.234
> Math.pow(36, 6) / 1000000 * 0.234 / 60
8.489451110400001
> Math.pow(62, 6) / 1000000 * 0.234 / 60 / 60
3.69201531296

使用6位純數(shù)字密碼,破解只要0.234秒!

使用6位數(shù)字+小寫字母密碼,破解只要8.49分鐘!

使用6位數(shù)字+大小寫混合字母密碼,破解只要3.69個(gè)小時(shí)!

當(dāng)然,使用長一點(diǎn)的密碼會(huì)顯著提高破解難度:

> Math.pow(10, 8) / 1000000 * 0.234
23.400000000000002
> Math.pow(36, 8) / 1000000 * 0.234 / 60 / 60 / 24
7.640505999359999
> Math.pow(62, 8) / 1000000 * 0.234 / 60 / 60 / 24 / 365
1.6201035231755982

使用8位純數(shù)字密碼,破解要23.4秒!

使用8位數(shù)字+小寫字母密碼,破解要7.64小時(shí)!

使用8位數(shù)字+大小寫混合字母密碼,破解要1.62年!

但是,別忘了,這個(gè)速度只是用PHP這個(gè)解釋型語言在筆者的弱雞個(gè)人電腦(i5-4460 CPU 3.20GHz)上跑出來的,還只是利用了一個(gè)線程一個(gè)CPU核心。若是放到最新的 Xeon E7 v4系列CPU的服務(wù)器上跑,充分利用其48個(gè)線程,并使用C語言來重寫下測試代碼,很容易就能提升個(gè)幾百上千倍速度。那么即使用8位數(shù)字+大小寫混合字母密碼,破解也只要14小時(shí)!

更何況,很多人的密碼都是采用比較有規(guī)律的字母或數(shù)字,更能降低暴力破解的難度... 如果沒有加鹽或加固定的鹽,那么彩虹表破解就更easy了...

那么如何提升密碼存儲(chǔ)的安全性呢?bcrypt!

提升安全性就是提升密碼的破解難度,至少讓暴力破解難度提升到攻擊者無法負(fù)擔(dān)的地步。(當(dāng)然用戶密碼的長度當(dāng)然也很重要,建議至少8位,越長越安全)

這里不得不插播一句:PHP果然是世界上最好的語言 -- 標(biāo)準(zhǔn)庫里面已經(jīng)給出了解決方案。

PHP 5.5 的版本中加入了 password_xxx 系列函數(shù), 而對之前的版本,也有兼容庫可以用:password_compat.
在這個(gè)名叫“密碼散列算法”的核心擴(kuò)展中提供了一系列簡潔明了的對密碼存儲(chǔ)封裝的函數(shù)。簡單介紹下:

password_hash 是對密碼進(jìn)行加密(hash),目前默認(rèn)用(也只能用)bcrypt算法,相當(dāng)于一個(gè)加強(qiáng)版的md5函數(shù)

password_verify 是一個(gè)驗(yàn)證密碼的函數(shù),內(nèi)部采用的安全的字符串比較算法,可以預(yù)防基于時(shí)間的攻擊, 相當(dāng)于 $hashedPassword === md5($inputPassword)

password_needs_rehash 是判斷是否需要升級的一個(gè)函數(shù),這個(gè)函數(shù)厲害了,下面再來詳細(xì)講

password_hash 需要傳入一個(gè)算法,現(xiàn)在默認(rèn)和可以使用的都只有bcrypt算法,這個(gè)算法是怎么樣的一個(gè)算法呢?為什么PHP標(biāo)準(zhǔn)庫里面會(huì)選擇bcrypt呢?

bcrypt是基于 Blowfish 算法的一種專門用于密碼哈希的算法,由 Niels Provos 和 David Mazieres 設(shè)計(jì)的。這個(gè)算法的特別之處在于,別的算法都是追求快,這個(gè)算法中有一個(gè)至關(guān)重要的參數(shù):cost. 正如其名,這個(gè)值越大,耗費(fèi)的時(shí)間越長,而且是指數(shù)級增長 -- 其加密流程中有一部分是這樣的:

EksBlowfishSetup(cost, salt, key)
    state <- InitState()
    state <- ExpandKey(state, salt, key)
    repeat (2^cost)                         // "^"表示指數(shù)關(guān)系
        state <- ExpandKey(state, 0, key)
        state <- ExpandKey(state, 0, salt)
    return state

比如下面是筆者的一次測試結(jié)果(個(gè)人弱機(jī)PC, i5-4460 CPU 3.20GHz) :

      cost       time
         8   0.021307
         9   0.037150
        10   0.079283
        11   0.175612
        12   0.317375
        13   0.663080
        14   1.330451
        15   2.245152
        16   4.291169
        17   8.318790
        18  16.472902
        19  35.146999

附:測試代碼

這個(gè)速度與md5相比簡直是蝸牛與獵豹的差別 -- 即使按照cost=8, 一個(gè)8位的大小寫字母+數(shù)字的密碼也要14萬年才能暴力破解掉,更何況一般服務(wù)器都會(huì)至少設(shè)置為10或更大的值(那就需要54萬年或更久了)。

顯然,cost不是越大越好,越大的話會(huì)越占用服務(wù)器的CPU,反而容易引起DOS攻擊。建議根據(jù)服務(wù)器的配置和業(yè)務(wù)的需求設(shè)置為10~12即可。最好同時(shí)對同一IP同一用戶的登錄嘗試次數(shù)做限制,預(yù)防DOS攻擊。

一個(gè)安全地存儲(chǔ)密碼的方案

總上所述,一個(gè)安全地存儲(chǔ)密碼的方案應(yīng)該是這樣子的:(直接放代碼吧)

class User extends BaseModel
{
    const PASSWORD_COST = 11; // 這里配置bcrypt算法的代價(jià),根據(jù)需要來隨時(shí)升級
    const PASSWORD_ALGO = PASSWORD_BCRYPT; // 默認(rèn)使用(現(xiàn)在也只能用)bcrypt

    /**
    * 驗(yàn)證密碼是否正確
    *
    * @param string $plainPassword 用戶密碼的明文
    * @param bool  $autoRehash    是否自動(dòng)重新計(jì)算下密碼的hash值(如果有必要的話)
    * @return bool
    */
    public function verifyPassword($plainPassword, $autoRehash = true)
    {
        if (password_verify($plainPassword, $this->password)) {
            if ($autoRehash && password_needs_rehash($this->password, self::PASSWORD_ALGO, ["cost" => self::PASSWORD_COST])) {
                $this->updatePassword($plainPassword);
            }

            return true;
        }

        return false;
    }

    /**
    * 更新密碼
    *
    * @param string $newPlainPassword
    */
    public function updatePassword($newPlainPassword)
    {
        $this->password = password_hash($newPlainPassword, self::PASSWORD_ALGO, ["cost" => self::PASSWORD_COST]);
        $this->save();
    }
}

這樣子,在用戶注冊或修改密碼的時(shí)候就調(diào)用 $user->updatePassword() 來設(shè)置密碼,而登錄的時(shí)候就調(diào)用 $user->verifyPassword() 來驗(yàn)證下密碼是否正確。
當(dāng)硬件性能提升到一定程度,而cost=11無法滿足安全需求的時(shí)候,則修改下 PASSWORD_COST 的值即可無縫升級,讓存放的密碼更安全。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/23048.html

相關(guān)文章

  • 當(dāng)我們在談?wù)撉岸思用軙r(shí),我們在談些什么

    摘要:所以我們今天只談前端加密,一個(gè)部分人認(rèn)為沒有意義的工作。在中,認(rèn)證過程使用了非對稱加密算法,非認(rèn)證過程中使用了對稱加密算法。非對稱加密上文中我們討論了前端的哈希加密以及應(yīng)用的場景。 showImg(https://segmentfault.com/img/bVAhTC); 當(dāng)然在談安全。 前端安全是Web安全的一部分,常見的安全問題會(huì)有XSS、CSRF、SQL注入等,然而這些已經(jīng)在程師...

    wizChen 評論0 收藏0
  • 常用加密算法探尋

    摘要:在開發(fā)過程中,常常用到各種加密方法和算法,本文總結(jié)了幾種常用加密方法的原理。非對稱加密原理非對稱加密算法需要兩個(gè)密鑰公開密鑰和私有密鑰。 在開發(fā)過程中,常常用到各種加密方法和算法,本文總結(jié)了幾種常用加密方法的原理。 對稱加密 showImg(https://segmentfault.com/img/bVbacxw?w=1128&h=468); 原理: 加密和解密數(shù)據(jù)使用同一個(gè)密鑰,適...

    Yu_Huang 評論0 收藏0
  • md5/sha1+salt and Bcrypt

    摘要:人們在微博上發(fā)表關(guān)于密碼和安全相關(guān)的消息。該條微博的作者強(qiáng)烈建議使用進(jìn)行加密。紅色級別的安全隱患比黃色級別嚴(yán)重很多。防止黃色級別并不是硬性要求。當(dāng)暴力破解失敗,唯一的辦法就是使用數(shù)據(jù)字典。在這種情況下,攻擊者只需進(jìn)行逐一計(jì)算。 PHP自帶的MD5和SHA1加密函數(shù)是否安全,看了很多年前的一篇博文。原文為英文,個(gè)人英語能力真的有限,翻譯了一下,其中必定存在很多錯(cuò)誤,希望各位可以指正。原文...

    史占廣 評論0 收藏0
  • md5/sha1+salt and Bcrypt

    摘要:人們在微博上發(fā)表關(guān)于密碼和安全相關(guān)的消息。該條微博的作者強(qiáng)烈建議使用進(jìn)行加密。紅色級別的安全隱患比黃色級別嚴(yán)重很多。防止黃色級別并不是硬性要求。當(dāng)暴力破解失敗,唯一的辦法就是使用數(shù)據(jù)字典。在這種情況下,攻擊者只需進(jìn)行逐一計(jì)算。 PHP自帶的MD5和SHA1加密函數(shù)是否安全,看了很多年前的一篇博文。原文為英文,個(gè)人英語能力真的有限,翻譯了一下,其中必定存在很多錯(cuò)誤,希望各位可以指正。原文...

    yvonne 評論0 收藏0
  • 一種低成本找回密碼token驗(yàn)證方案

    摘要:的特點(diǎn)主要有如下幾個(gè)唯一性時(shí)效性不可預(yù)測很多大型業(yè)務(wù)中,比如說的找回密碼流程中,對于發(fā)給用戶的找回密碼鏈接郵件需要同時(shí)提交用戶輸入的驗(yàn)證碼和也就是該校驗(yàn)碼對應(yīng)的。 隨著互聯(lián)網(wǎng)的高速發(fā)展,WEB2.0網(wǎng)站的業(yè)務(wù)越來越龐大,一些token驗(yàn)證在許多場景下都必不可少,比如說交易訂單的防止多次提交,重要的敏感操作防止CSRF(跨站請求偽造)攻擊,以及短信驗(yàn)證碼,找回密碼驗(yàn)證碼,注冊登錄圖形的生...

    lakeside 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<