成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

md5安全嗎?有多么地不安全?如何才能安全地存儲密碼?…

md5安全嗎?

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

這兒有個腳本來測試下MD5的速度, 測試結果:

  1. [root@f4d5945f1d7c tools]# php speed-of-md5.php 
  2. Array 
  3.     [rounds] => 100 
  4.     [times of a round] => 1000000 
  5.     [avg] => 0.23415904045105 
  6.     [max] => 0.28906106948853 
  7.     [min] => 0.21188998222351 
  8.  

有沒有發現一個問題:MD5速度太快了,導致很容易進行暴力破解.

簡單計算一下:

  1. > Math.pow(10, 6) / 1000000 * 0.234 
  2. 0.234 
  3. > Math.pow(36, 6) / 1000000 * 0.234 / 60 
  4. 8.489451110400001 
  5. > Math.pow(62, 6) / 1000000 * 0.234 / 60 / 60 
  6. 3.69201531296  
  1. 使用6位純數字密碼,破解只要0.234秒!
  2. 使用6位數字+小寫字母密碼,破解只要8.49分鐘!
  3. 使用6位數字+大小寫混合字母密碼,破解只要3.69個小時!

當然,使用長一點的密碼會顯著提高破解難度:

  1. > Math.pow(10, 8) / 1000000 * 0.234 
  2. 23.400000000000002 
  3. > Math.pow(36, 8) / 1000000 * 0.234 / 60 / 60 / 24 
  4. 7.640505999359999 
  5. > Math.pow(62, 8) / 1000000 * 0.234 / 60 / 60 / 24 / 365 
  6. 1.6201035231755982  
  1. 使用8位純數字密碼,破解要23.4秒!
  2. 使用8位數字+小寫字母密碼,破解要7.64小時!
  3. 使用8位數字+大小寫混合字母密碼,破解要1.62年!

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

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

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

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

這里不得不插播一句:PHP果然是世界上最好的語言 — 標準庫里面已經給出了解決方案。

PHP 5.5 的版本中加入了 password_xxx 系列函數, 而對之前的版本,也有兼容庫可以用:password_compat.

在這個名叫“密碼散列算法”的核心擴展中提供了一系列簡潔明了的對密碼存儲封裝的函數。簡單介紹下:

  1. password_hash 是對密碼進行加密(hash),目前默認用(也只能用)bcrypt算法,相當于一個加強版的md5函數
  2. password_verify 是一個驗證密碼的函數,內部采用的安全的字符串比較算法,可以預防基于時間的攻擊, 相當于 $hashedPassword === md5($inputPassword)
  3. password_needs_rehash 是判斷是否需要升級的一個函數,這個函數厲害了,下面再來詳細講

password_hash 需要傳入一個算法,現在默認和可以使用的都只有bcrypt算法,這個算法是怎么樣的一個算法呢?為什么PHP標準庫里面會選擇bcrypt呢?

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

  1. EksBlowfishSetup(cost, salt, key
  2.     state <- InitState() 
  3.     state <- ExpandKey(state, salt, key
  4.     repeat (2^cost)                         // "^"表示指數關系 
  5.         state <- ExpandKey(state, 0, key
  6.         state <- ExpandKey(state, 0, salt) 
  7.     return state  

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

  1. cost       time 
  2.          8   0.021307 
  3.          9   0.037150 
  4.         10   0.079283 
  5.         11   0.175612 
  6.         12   0.317375 
  7.         13   0.663080 
  8.         14   1.330451 
  9.         15   2.245152 
  10.         16   4.291169 
  11.         17   8.318790 
  12.         18  16.472902 
  13.         19  35.146999  

附:測試代碼

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

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

一個安全地存儲密碼的方案

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

  1. class User extends BaseModel 
  2.     const PASSWORD_COST = 11; // 這里配置bcrypt算法的代價,根據需要來隨時升級 
  3.     const PASSWORD_ALGO = PASSWORD_BCRYPT; // 默認使用(現在也只能用)bcrypt 
  4.  
  5.     /** 
  6.     * 驗證密碼是否正確 
  7.     * 
  8.     * @param string $plainPassword 用戶密碼的明文 
  9.     * @param bool  $autoRehash    是否自動重新計算下密碼的hash值(如果有必要的話) 
  10.     * @return bool 
  11.     */ 
  12.     public function verifyPassword($plainPassword, $autoRehash = true
  13.     { 
  14.         if (password_verify($plainPassword, $this->password)) { 
  15.             if ($autoRehash && password_needs_rehash($this->password, self::PASSWORD_ALGO, ['cost' => self::PASSWORD_COST])) { 
  16.                 $this->updatePassword($plainPassword); 
  17.             } 
  18.  
  19.             return true
  20.         } 
  21.  
  22.         return false
  23.     } 
  24.  
  25.     /** 
  26.     * 更新密碼 
  27.     * 
  28.     * @param string $newPlainPassword 
  29.     */ 
  30.     public function updatePassword($newPlainPassword) 
  31.     { 
  32.         $this->password = password_hash($newPlainPassword, self::PASSWORD_ALGO, ['cost' => self::PASSWORD_COST]); 
  33.         $this->save(); 
  34.     } 
  35.  

這樣子,在用戶注冊或修改密碼的時候就調用 $user->updatePassword() 來設置密碼,而登錄的時候就調用 $user->verifyPassword() 來驗證下密碼是否正確。

當硬件性能提升到一定程度,而cost=11無法滿足安全需求的時候,則修改下 PASSWORD_COST 的值即可無縫升級,讓存放的密碼更安全。 

責任編輯:龐桂玉 來源: Android開發中文站
相關推薦

2015-03-23 11:21:08

2022-10-18 22:21:51

2009-11-03 13:46:56

Oracle密碼

2010-04-02 13:53:47

2016-12-15 09:26:53

MD5加密

2009-05-05 17:52:48

系統安全密碼安全Windows

2019-06-14 05:00:05

2009-04-27 10:39:47

視頻會議存儲安全

2021-12-06 18:16:14

SQLCRCMD5

2010-05-04 17:43:50

Unix系統

2013-04-02 13:06:20

BYODBYOD安全

2020-10-15 08:20:52

MD5算法加密的過程

2009-06-06 18:57:47

MD5加密類Java Bean

2012-11-20 10:47:16

2012-05-30 16:25:30

密碼安全

2011-07-14 14:21:11

2014-07-28 11:18:30

件測試云計算云測試

2011-12-28 13:14:39

2018-08-29 12:05:54

云數據存儲安全

2010-03-16 09:27:31

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99精品99| 韩国主播午夜大尺度福利 | 国内自拍视频在线观看 | 少妇一级淫片aaaaaaaaa | 天天干视频 | 91伊人 | 亚洲第一成年免费网站 | 久久久久久高潮国产精品视 | 九九九视频精品 | 久久久亚洲一区 | 中文字幕在线观看第一页 | 在线观看免费高清av | 亚洲色图综合 | 日日天天| 精品一区二区三区在线观看 | 一级做a毛片 | 日韩中文久久 | 日韩欧美网 | 欧美日韩一区二区在线观看 | 国产在线91| k8久久久一区二区三区 | 91精品国产91久久久 | 密色视频 | 一级片网址 | 99热在线免费 | 成人一级黄色毛片 | www..com18午夜观看 | 91久久综合亚洲鲁鲁五月天 | 日本一区二区三区四区 | 国产精品一区一区三区 | 日韩视频在线免费观看 | 一区二区视频在线 | 久久久久久九九九九九九 | 欧美日韩精品免费观看 | 色女人天堂 | 最新日韩av| 国产精品免费视频一区 | 日韩a在线观看 | 日本a∨精品中文字幕在线 亚洲91视频 | 91精品国产欧美一区二区成人 | 亚洲国产精品日本 |