在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 9.5 存儲密碼
7 文本處理
3 Web基礎(chǔ)
14 擴展Web框架
10.4 小結(jié)
2.2 Go基礎(chǔ)
2.8 總結(jié)
6.1 session和cookie
5.5 使用beedb庫進行ORM開發(fā)
8.3 REST
13.6 小結(jié)
5.4 使用PostgreSQL數(shù)據(jù)庫
14.6 pprof支持
14.1 靜態(tài)文件支持
11.2 使用GDB調(diào)試
7.7 小結(jié)
1 GO環(huán)境配置
14.5 多語言支持
7.1 XML處理
1.5 總結(jié)
13 如何設(shè)計一個Web框架
14.3 表單及驗證支持
12 部署與維護
10 國際化和本地化
1.1 Go 安裝
6.2 Go如何使用session
5.6 NOSQL數(shù)據(jù)庫操作
6.5 小結(jié)
9.4 避免SQL注入
12.1 應(yīng)用日志
4.2 驗證表單的輸入
10.1 設(shè)置默認地區(qū)
1.3 Go 命令
9.6 加密和解密數(shù)據(jù)
4.1 處理表單的輸入
4.4 防止多次遞交表單
11.3 Go怎么寫測試用例
8 Web服務(wù)
12.3 應(yīng)用部署
5.7 小結(jié)
12.5 小結(jié)
11 錯誤處理,調(diào)試和測試
9.2 確保輸入過濾
14.2 Session支持
6.4 預(yù)防session劫持
12.4 備份和恢復(fù)
8.1 Socket編程
13.1 項目規(guī)劃
13.4 日志和配置設(shè)計
7.6 字符串處理
13.2 自定義路由器設(shè)計
6.3 session存儲
3.4 Go的http包詳解
8.2 WebSocket
10.3 國際化站點
7.5 文件操作
7.4 模板處理
9.1 預(yù)防CSRF攻擊
13.3 controller設(shè)計
2.6 interface
14.4 用戶認證
2.3 流程和函數(shù)
附錄A 參考資料
11.1 錯誤處理
9.5 存儲密碼
9.3 避免XSS攻擊
12.2 網(wǎng)站錯誤處理
6 session和數(shù)據(jù)存儲
2.4 struct類型
3.3 Go如何使得Web工作
2.5 面向?qū)ο?/span>
3.1 Web工作方式
1.2 GOPATH與工作空間
2.1 你好,Go
9.7 小結(jié)
13.5 實現(xiàn)博客的增刪改
7.2 JSON處理
10.2 本地化資源
7.3 正則處理
2 Go語言基礎(chǔ)
5.1 database/sql接口
4.5 處理文件上傳
8.5 小結(jié)
4.3 預(yù)防跨站腳本
5.3 使用SQLite數(shù)據(jù)庫
14.7 小結(jié)
3.2 Go搭建一個Web服務(wù)器
2.7 并發(fā)
5 訪問數(shù)據(jù)庫
4 表單
3.5 小結(jié)
1.4 Go開發(fā)工具
11.4 小結(jié)
9 安全與加密
5.2 使用MySQL數(shù)據(jù)庫
4.6 小結(jié)
8.4 RPC

9.5 存儲密碼

過去一段時間以來, 許多的網(wǎng)站遭遇用戶密碼數(shù)據(jù)泄露事件, 這其中包括頂級的互聯(lián)網(wǎng)企業(yè)–Linkedin, 國內(nèi)諸如CSDN,該事件橫掃整個國內(nèi)互聯(lián)網(wǎng),隨后又爆出多玩游戲800萬用戶資料被泄露,另有傳言人人網(wǎng)、開心網(wǎng)、天涯社區(qū)、世紀佳緣、百合網(wǎng)等社區(qū)都有可能成為黑客下一個目標。層出不窮的類似事件給用戶的網(wǎng)上生活造成巨大的影響,人人自危,因為人們往往習(xí)慣在不同網(wǎng)站使用相同的密碼,所以一家“暴庫”,全部遭殃。

那么我們作為一個Web應(yīng)用開發(fā)者,在選擇密碼存儲方案時, 容易掉入哪些陷阱, 以及如何避免這些陷阱?

普通方案

目前用的最多的密碼存儲方案是將明文密碼做單向哈希后存儲,單向哈希算法有一個特征:無法通過哈希后的摘要(digest)恢復(fù)原始數(shù)據(jù),這也是“單向”二字的來源。常用的單向哈希算法包括SHA-256, SHA-1, MD5等。

Go語言對這三種加密算法的實現(xiàn)如下所示:

//import "crypto/sha256"
h := sha256.New()
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))

//import "crypto/sha1"
h := sha1.New()
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))

//import "crypto/md5"
h := md5.New()
io.WriteString(h, "需要加密的密碼")
fmt.Printf("%x", h.Sum(nil))

單向哈希有兩個特性:

  • 1)同一個密碼進行單向哈希,得到的總是唯一確定的摘要。
  • 2)計算速度快。隨著技術(shù)進步,一秒鐘能夠完成數(shù)十億次單向哈希計算。

結(jié)合上面兩個特點,考慮到多數(shù)人所使用的密碼為常見的組合,攻擊者可以將所有密碼的常見組合進行單向哈希,得到一個摘要組合, 然后與數(shù)據(jù)庫中的摘要進行比對即可獲得對應(yīng)的密碼。這個摘要組合也被稱為rainbow table。

因此通過單向加密之后存儲的數(shù)據(jù),和明文存儲沒有多大區(qū)別。因此,一旦網(wǎng)站的數(shù)據(jù)庫泄露,所有用戶的密碼本身就大白于天下。

進階方案

通過上面介紹我們知道黑客可以用rainbow table來破解哈希后的密碼,很大程度上是因為加密時使用的哈希算法是公開的。如果黑客不知道加密的哈希算法是什么,那他也就無從下手了。

一個直接的解決辦法是,自己設(shè)計一個哈希算法。然而,一個好的哈希算法是很難設(shè)計的——既要避免碰撞,又不能有明顯的規(guī)律,做到這兩點要比想象中的要困難很多。因此實際應(yīng)用中更多的是利用已有的哈希算法進行多次哈希。

但是單純的多次哈希,依然阻擋不住黑客。兩次 MD5、三次 MD5之類的方法,我們能想到,黑客自然也能想到。特別是對于一些開源代碼,這樣哈希更是相當(dāng)于直接把算法告訴了黑客。

沒有攻不破的盾,但也沒有折不斷的矛?,F(xiàn)在安全性比較好的網(wǎng)站,都會用一種叫做“加鹽”的方式來存儲密碼,也就是常說的 “salt”。他們通常的做法是,先將用戶輸入的密碼進行一次MD5(或其它哈希算法)加密;將得到的 MD5 值前后加上一些只有管理員自己知道的隨機串,再進行一次MD5加密。這個隨機串中可以包括某些固定的串,也可以包括用戶名(用來保證每個用戶加密使用的密鑰都不一樣)。

//import "crypto/md5"
//假設(shè)用戶名abc,密碼123456
h := md5.New()
io.WriteString(h, "需要加密的密碼")

//pwmd5等于e10adc3949ba59abbe56e057f20f883e
pwmd5 :=fmt.Sprintf("%x", h.Sum(nil))

//指定兩個 salt: salt1 = @#$%   salt2 = ^&*()
salt1 := "@#$%"
salt2 := "^&*()"

//salt1+用戶名+salt2+MD5拼接
io.WriteString(h, salt1)
io.WriteString(h, "abc")
io.WriteString(h, salt2)
io.WriteString(h, pwmd5)

last :=fmt.Sprintf("%x", h.Sum(nil))

在兩個salt沒有泄露的情況下,黑客如果拿到的是最后這個加密串,就幾乎不可能推算出原始的密碼是什么了。

專家方案

上面的進階方案在幾年前也許是足夠安全的方案,因為攻擊者沒有足夠的資源建立這么多的rainbow table。 但是,時至今日,因為并行計算能力的提升,這種攻擊已經(jīng)完全可行。

怎么解決這個問題呢?只要時間與資源允許,沒有破譯不了的密碼,所以方案是:故意增加密碼計算所需耗費的資源和時間,使得任何人都不可獲得足夠的資源建立所需的rainbow table

這類方案有一個特點,算法中都有個因子,用于指明計算密碼摘要所需要的資源和時間,也就是計算強度。計算強度越大,攻擊者建立rainbow table越困難,以至于不可繼續(xù)。

這里推薦scrypt方案,scrypt是由著名的FreeBSD黑客Colin Percival為他的備份服務(wù)Tarsnap開發(fā)的。

目前Go語言里面支持的庫http://code.google.com/p/go/source/browse?repo=crypto#hg%2Fscrypt

dk := scrypt.Key([]byte("some password"), []byte(salt), 16384, 8, 1, 32)

通過上面的的方法可以獲取唯一的相應(yīng)的密碼值,這是目前為止最難破解的。

總結(jié)

看到這里,如果你產(chǎn)生了危機感,那么就行動起來:

  • 1)如果你是普通用戶,那么我們建議使用LastPass進行密碼存儲和生成,對不同的網(wǎng)站使用不同的密碼;
  • 2)如果你是開發(fā)人員, 那么我們強烈建議你采用專家方案進行密碼存儲。