golang使用bcrypt包對(duì)密碼進(jìn)行加密的方法實(shí)現(xiàn)
bcrypt
bcrypt是一個(gè)由美國計(jì)算機(jī)科學(xué)家尼爾斯·普羅沃斯(Niels Provos)以及大衛(wèi)·馬齊耶(David Mazières)根據(jù)Blowfish加密算法所設(shè)計(jì)的密碼散列函數(shù),于1999年在USENIX中展示。實(shí)現(xiàn)中bcrypt會(huì)使用一個(gè)加鹽的流程以防御彩虹表攻擊,同時(shí)bcrypt還是適應(yīng)性函數(shù),它可以借由增加迭代之次數(shù)來抵御日益增進(jìn)的電腦運(yùn)算能力透過暴力法破解。
由bcrypt加密的文件可在所有支持的操作系統(tǒng)和處理器上進(jìn)行轉(zhuǎn)移。它的口令必須是8至56個(gè)字符,并將在內(nèi)部被轉(zhuǎn)化為448位的密鑰。然而,所提供的所有字符都具有十分重要的意義。密碼越強(qiáng)大,數(shù)據(jù)就越安全。
除了對(duì)數(shù)據(jù)進(jìn)行加密,默認(rèn)情況下,bcrypt在刪除數(shù)據(jù)之前將使用隨機(jī)數(shù)據(jù)三次覆蓋原始輸入文件,以阻撓可能會(huì)獲得計(jì)算機(jī)數(shù)據(jù)的人恢復(fù)數(shù)據(jù)的嘗試。如果您不想使用此功能,可設(shè)置禁用此功能。
bcrypt哈希示意圖
下圖為bcrypt哈希的示例圖,其由四部分組成:
- Prefix說明了使用的bcrypt的版本
- Cost是進(jìn)行哈希的次數(shù)-數(shù)字越大生成bcrypt的速度越慢,成本越大。同樣也意味著如果密碼庫被盜,攻擊者想通過暴力破解的方法猜測(cè)出用戶密碼的成本變得越昂貴。
- Salt是添加到要進(jìn)行哈希的字符串中的隨機(jī)字符(21.25個(gè)字符),所以使用bcrypt時(shí)不需要我們?cè)诒砝飭为?dú)存儲(chǔ)Salt。
- Hashed Text是明文字符串最終被bcrypt應(yīng)用這些設(shè)置哈希后的哈希文本。
- 另外無論什么方法:每個(gè)密碼加單獨(dú)的鹽進(jìn)行哈希,使用bcrypt進(jìn)行哈希等等,如果用戶使用非常簡單的密碼例如password或123456,還是能被猜測(cè)出來的,所以在用戶設(shè)置密碼時(shí)應(yīng)該禁止他們輸入簡單的密碼。
go語言中使用bcrypt對(duì)密碼進(jìn)行加密
go語言庫中,bcrypt只能做單向加密,而不能反向破解生成明文,但是可以對(duì)原密碼和進(jìn)行hash加密后的hash值進(jìn)行比對(duì)判斷是否相同,使用bcrypt進(jìn)行加密,同一個(gè)密碼每次生成的hash值都是不相同的。每次加密的時(shí)候首先會(huì)生成一個(gè)隨機(jī)數(shù)就是鹽,之后將這個(gè)隨機(jī)數(shù)與密碼進(jìn)行hash。
// 加密密碼 func HashAndSalt(pwd string) string { hash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.MinCost) if err != nil { log.Println(err) } return string(hash) } // 驗(yàn)證密碼 func ComparePasswords(hashedPwd string, plainPwd string) bool { byteHash := []byte(hashedPwd) err := bcrypt.CompareHashAndPassword(byteHash, []byte(plainPwd)) if err != nil { log.Println(err) return false } return true }
這里簡單對(duì)兩個(gè)方法封裝了一下,方便后期調(diào)用。
在go語言中,bcrypt.GenerateFromPassword()
是對(duì)字符串進(jìn)行加密hash的函數(shù),其中第一個(gè)參數(shù)[]byte(pwd)
是對(duì)原字符串轉(zhuǎn)換為字節(jié)切片,第二個(gè)參數(shù)bcrypt.MinCost
為對(duì)字符串進(jìn)行哈希的次數(shù),也就是上圖中的Cost。bcrypt.CompareHashAndPassword()
是對(duì)hash過的字符串和原字符串進(jìn)行判斷,其中第一個(gè)參數(shù)byteHash
是hash加密過的hash值,第二個(gè)參數(shù)[]byte(plainPwd)
是原字符串,bcrypt.CompareHashAndPassword()
進(jìn)行判斷兩個(gè)參數(shù)是否一個(gè)值。
示例:
func main() { pwd1 := "wlc1003.." pwd2 := "wlc1003.." pwd3 := "wlc1003" hash1 := utils.HashAndSalt(pwd1) hash2 := utils.HashAndSalt(pwd2) hash3 := utils.HashAndSalt(pwd3) fmt.Println(hash1) fmt.Println(hash2) fmt.Println(hash3) fmt.Println(utils.ComparePasswords(hash2, pwd1)) fmt.Println(utils.ComparePasswords(hash3, pwd2)) fmt.Println(utils.ComparePasswords(hash1, pwd2)) }
//輸出
$2a$04$4MXIN0OQeiKf7HI.eKYw6eRM1mcjDrItX0wzgOSVgkczsvFj8ifuW
$2a$04$aJz4S67m.CTTP3gBiKoVZu3CTMujCImTqcUaPppcKzoUXtsIR.Z5.
$2a$04$OVXCGxnkIpvFSegtq20hHOhtvMwFIRp.iBog4E62CS9uaQ/PlDH5Strue
2023/07/16 21:53:24 crypto/bcrypt: hashedPassword is not the hash of the given password //表示不匹配
false
true
到此這篇關(guān)于golang使用bcrypt包對(duì)密碼進(jìn)行加密的方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)golang bcrypt密碼加密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言LeetCode題解706設(shè)計(jì)哈希映射
這篇文章主要為大家介紹了Go語言LeetCode題解706設(shè)計(jì)哈希映射示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Go語言并發(fā)編程之互斥鎖Mutex和讀寫鎖RWMutex
Go 語言中提供了很多同步工具,本文將介紹互斥鎖Mutex和讀寫鎖RWMutex的使用方法,想要具體了解的小伙伴,請(qǐng)參考下面文章詳細(xì)內(nèi)容,希望對(duì)你有所幫助2021-10-10使用gin框架搭建簡易服務(wù)的實(shí)現(xiàn)方法
go語言web框架挺多的,本文就介紹了一下如何使用gin框架搭建簡易服務(wù)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12創(chuàng)建第一個(gè)Go語言程序Hello,Go!
這篇文章主要介紹了創(chuàng)建第一個(gè)Go語言程序Hello,Go!本文詳細(xì)的給出項(xiàng)目創(chuàng)建、代碼編寫的過程,同時(shí)講解了GOPATH、Go install等內(nèi)容,需要的朋友可以參考下2014-10-10gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼
這篇文章主要介紹了gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11手把手教你vscode配置golang開發(fā)環(huán)境的步驟
這篇文章主要介紹了手把手教你vscode配置golang開發(fā)環(huán)境的步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03