Golang常用的幾種密碼加密方式分享
加密方式
加密有兩種方式,一種是直接加密,一種是鹽值加密
**直接加密(Plain Hashing)**指的是將原始密碼直接進(jìn)行加密,而不進(jìn)行任何額外的操作。這種方式可能存在一些安全風(fēng)險(xiǎn),因?yàn)橄嗤拿艽a在經(jīng)過(guò)加密后會(huì)得到相同的哈希值,容易受到彩虹表攻擊等攻擊方式的影響。
**鹽值加密(Salted Hashing)**則是在進(jìn)行密碼加密之前,將密碼與一個(gè)隨機(jī)生成的鹽值進(jìn)行拼接。通過(guò)將鹽值與密碼組合后再進(jìn)行哈希,可以確保即使密碼相同,由于鹽值不同,生成的哈希值也會(huì)不同。這樣可以增加密碼的安全性,防止彩虹表攻擊等。
為什么被稱為鹽值?
"鹽值"(Salt)一詞的使用源自于密碼學(xué)的術(shù)語(yǔ)。在密碼學(xué)中,"鹽"是指一個(gè)隨機(jī)生成的值,用于增加密碼哈希函數(shù)的安全性。
這個(gè)術(shù)語(yǔ)的由來(lái)是因?yàn)辂}在密碼哈希過(guò)程中的作用類似于在烹飪中使用的鹽。在烹飪中,鹽用于增添食物的味道,并且不同的鹽可以帶來(lái)不同的風(fēng)味。類比到密碼學(xué)中,鹽用于增加密碼的安全性,并且不同的鹽可以為相同的密碼帶來(lái)不同的哈希值。
鹽值的主要目的是增加密碼的破解難度。通過(guò)將鹽值與密碼進(jìn)行組合后再進(jìn)行哈希,即使兩個(gè)用戶使用相同的密碼,由于鹽值不同,最終的哈希值也會(huì)不同。這樣一來(lái),攻擊者無(wú)法通過(guò)對(duì)比哈希值來(lái)確定是否存在相同的密碼。
另外,使用隨機(jī)生成的鹽值還可以防止預(yù)先計(jì)算的攻擊,例如彩虹表攻擊。彩虹表是一種預(yù)先計(jì)算出密碼哈希值與明文密碼之間的映射關(guān)系的攻擊技術(shù),通過(guò)事先計(jì)算大量密碼的哈希值并存儲(chǔ)在表中,可以快速地找到對(duì)應(yīng)的明文密碼。但是,當(dāng)使用鹽值時(shí),即使明文密碼相同,由于鹽值不同,生成的哈希值也不同,使得彩虹表攻擊無(wú)效。
因此,鹽值在密碼存儲(chǔ)和驗(yàn)證過(guò)程中起著重要的作用,是一種常見的增強(qiáng)密碼安全性的方式之一。
加密方法
1. Bcrypt
Bcrypt 是一個(gè)基于 Blowfish 密碼哈希函數(shù)的密碼加密算法。它是一個(gè)常見且可靠的選擇,具有適度的計(jì)算復(fù)雜性,可以防止暴力破解和彩虹表攻擊。
**Bcrypt 加密函數(shù)會(huì)自動(dòng)生成鹽值并將其嵌入到生成的哈希值中。**在 Bcrypt 哈希值的格式中,前面部分是一個(gè)包含算法標(biāo)識(shí)、鹽值和其他必要信息的字符串,后面部分是實(shí)際的密碼哈希值。
Bcrypt 會(huì)自動(dòng)處理鹽值的生成和存儲(chǔ),你不需要顯式地提供鹽值作為參數(shù)。每個(gè)密碼的鹽值都是隨機(jī)生成的,并且與哈希值一起存儲(chǔ)在結(jié)果中。這樣做的目的是增加密碼哈希的安全性,使每個(gè)密碼都使用不同的鹽值進(jìn)行哈希,即使相同的密碼在不同用戶之間也會(huì)生成不同的哈希值。
因此,**當(dāng)你使用 Bcrypt 進(jìn)行密碼加密時(shí),你只需要提供密碼作為輸入,而不需要單獨(dú)提供鹽值。**Bcrypt 會(huì)自動(dòng)為每個(gè)密碼生成并使用不同的隨機(jī)鹽值。在驗(yàn)證密碼時(shí),Bcrypt 會(huì)從存儲(chǔ)的哈希值中提取鹽值,并將其與輸入密碼一起使用來(lái)進(jìn)行驗(yàn)證。這樣,你無(wú)需擔(dān)心鹽值的管理和處理,Bcrypt 會(huì)為你處理這些細(xì)節(jié)。
安裝
go get -u golang.org/x/crypto/bcrypt
導(dǎo)入包
import "golang.org/x/crypto/bcrypt"
加密
// HashPassword 使用 Bcrypt 算法生成密碼哈希值 func HashPassword(password string) (string, error) { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return "", err } return string(hashedPassword), nil }
驗(yàn)證
// ComparePasswords 比較輸入的密碼與哈希值是否匹配 func ComparePasswords(hashedPassword, password string) bool { err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) return err == nil }
加密驗(yàn)證示例
2. Argon2
Argon2 是一個(gè)密碼哈希函數(shù),被選為 Password Hashing Competition (密碼哈希競(jìng)賽)的獲勝者。它是一個(gè)現(xiàn)代的、安全的密碼哈希算法,提供了防止側(cè)信道攻擊和抵抗 GPU 加速的能力。
Argon2 密碼哈希函數(shù)將密碼加密后的結(jié)果通常呈現(xiàn)為亂碼。這是因?yàn)樗鼈兪褂昧藦?qiáng)大的哈希算法和鹽值,將密碼轉(zhuǎn)換為一個(gè)不可逆的哈希值。
這些哈希值通常是二進(jìn)制數(shù)據(jù),不適合直接用于存儲(chǔ)或傳輸。**為了安全地存儲(chǔ)和比較密碼,你應(yīng)該將哈希值轉(zhuǎn)換為字符串形式進(jìn)行存儲(chǔ)。**我這里就不寫轉(zhuǎn) base64 格式了,展示一下亂碼
安裝
go get -u golang.org/x/crypto/argon2
導(dǎo)入包
import "golang.org/x/crypto/argon2"
加密
// HashPassword 使用 Argon2 算法生成密碼哈希值 func HashPassword(password, salt string) (string, error) { time := uint32(1) // 迭代次數(shù) memory := uint32(64 * 1024) // 內(nèi)存使用量(以字節(jié)為單位) threads := uint8(4) // 并行線程數(shù) keyLen := uint32(32) // 輸出密鑰長(zhǎng)度為 32 字節(jié) hashedPassword := argon2.IDKey([]byte(password), []byte(salt), time, memory, threads, keyLen) return string(hashedPassword), nil }
驗(yàn)證
驗(yàn)證使用 Go 語(yǔ)言標(biāo)準(zhǔn)庫(kù)中 crypto/subtle
包中的一個(gè)函數(shù)ConstantTimeCompare
,用于在恒定時(shí)間內(nèi)比較兩個(gè)字節(jié)切片(byte slices)的內(nèi)容
// ComparePasswords 驗(yàn)證密碼是否匹配 func ComparePasswords(hashedPassword, password, salt string) bool { time := uint32(1) // 迭代次數(shù) memory := uint32(64 * 1024) // 內(nèi)存使用量(以字節(jié)為單位) threads := uint8(4) // 并行線程數(shù) keyLen := uint32(32) // 輸出密鑰長(zhǎng)度為 32 字節(jié) derivedKey := argon2.IDKey([]byte(password), []byte(salt), time, memory, threads, keyLen) return subtle.ConstantTimeCompare([]byte(hashedPassword), derivedKey) == 1 }
加密驗(yàn)證示例
3. Scrypt
Scrypt 是一種基于密碼學(xué)的 key-derivation function(密鑰派生函數(shù)),主要用于密碼加密和密鑰衍生。它相對(duì)于一些其他算法,如 MD5 和 SHA-2,具有更高的計(jì)算復(fù)雜性。
Scrypt 密碼哈希函數(shù)將密碼加密后的結(jié)果通常呈現(xiàn)為亂碼。這是因?yàn)樗鼈兪褂昧藦?qiáng)大的哈希算法和鹽值,將密碼轉(zhuǎn)換為一個(gè)不可逆的哈希值。
這些哈希值通常是二進(jìn)制數(shù)據(jù),不適合直接用于存儲(chǔ)或傳輸。**為了安全地存儲(chǔ)和比較密碼,你應(yīng)該將哈希值轉(zhuǎn)換為字符串形式進(jìn)行存儲(chǔ)。**我這里就不寫轉(zhuǎn) base64 格式了,展示一下亂碼
安裝
go get -u golang.org/x/crypto/scrypt
導(dǎo)入包
import "golang.org/x/crypto/scrypt"
加密
// HashPassword 使用 Scrypt 算法生成密碼哈希值 func HashPassword(password, salt string) (string, error) { N := 16384 // 迭代次數(shù),表示對(duì)哈希函數(shù)的重復(fù)計(jì)算次數(shù)。值越大,計(jì)算成本越高,安全性越好,但性能也會(huì)受到影響。通常建議選擇一個(gè)大于 2^14 的值,例如 16384 r := 8 // 塊大小,表示每次哈希計(jì)算中使用的內(nèi)存塊大小。較大的值會(huì)增加內(nèi)存消耗,并增加攻擊成本。通常建議選擇一個(gè)合適的值,例如 8 p := 1 // 并行度,表示并行計(jì)算的線程或處理器數(shù)目。較高的值會(huì)增加計(jì)算成本,適當(dāng)?shù)闹等Q于你的硬件配置。通常建議選擇一個(gè)合適的值,例如 1 keyLen := 32 // 參數(shù)指定生成的密鑰的長(zhǎng)度 hashedPassword, err := scrypt.Key([]byte(password), []byte(salt), N, r, p, keyLen) if err != nil { return "", err } return string(hashedPassword), nil }
驗(yàn)證
驗(yàn)證使用 Go 語(yǔ)言標(biāo)準(zhǔn)庫(kù)中 crypto/subtle
包中的一個(gè)函數(shù)ConstantTimeCompare
,用于在恒定時(shí)間內(nèi)比較兩個(gè)字節(jié)切片(byte slices)的內(nèi)容
// ComparePasswords 驗(yàn)證密碼是否匹配 func ComparePasswords(hashedPassword, password, salt string) bool { N := 16384 // 迭代次數(shù),表示對(duì)哈希函數(shù)的重復(fù)計(jì)算次數(shù)。值越大,計(jì)算成本越高,安全性越好,但性能也會(huì)受到影響。通常建議選擇一個(gè)大于 2^14 的值,例如 16384 r := 8 // 塊大小,表示每次哈希計(jì)算中使用的內(nèi)存塊大小。較大的值會(huì)增加內(nèi)存消耗,并增加攻擊成本。通常建議選擇一個(gè)合適的值,例如 8 p := 1 // 并行度,表示并行計(jì)算的線程或處理器數(shù)目。較高的值會(huì)增加計(jì)算成本,適當(dāng)?shù)闹等Q于你的硬件配置。通常建議選擇一個(gè)合適的值,例如 1 keyLen := 32 // 參數(shù)指定生成的密鑰的長(zhǎng)度 derivedKey, err := scrypt.Key([]byte(password), []byte(salt), N, r, p, keyLen) if err != nil { return false } return subtle.ConstantTimeCompare([]byte(hashedPassword), derivedKey) == 1 }
到此這篇關(guān)于Golang常用的幾種密碼加密方式分享的文章就介紹到這了,更多相關(guān)Golang密碼加密方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang簡(jiǎn)單實(shí)現(xiàn)http的server端和client端
Http 服務(wù)是基于 Tcp 的應(yīng)用層的實(shí)現(xiàn),也是最常見的網(wǎng)絡(luò)協(xié)議之一。本文主要介紹了Golang簡(jiǎn)單實(shí)現(xiàn)http的server端和client端,感興趣的可以了解一下2021-06-06Go語(yǔ)言使用templ實(shí)現(xiàn)編寫HTML用戶界面
templ是一個(gè)在 Go 中編寫 HTML 用戶界面的語(yǔ)言,使用 templ,我們可以創(chuàng)建可呈現(xiàn) HTML 片段的組件,下面就跟隨小編一起了解一下具體的實(shí)現(xiàn)方法吧2023-12-12go的defer和閉包示例說(shuō)明(非內(nèi)部實(shí)現(xiàn))
這篇文章主要為大家介紹了go的defer和閉包示例說(shuō)明(非內(nèi)部實(shí)現(xiàn)),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之希爾排序示例詳解
這篇文章主要為大家介紹了Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之希爾排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08深入理解Go高級(jí)并發(fā)模式編寫更高效可擴(kuò)展的應(yīng)用程序
Go對(duì)并發(fā)提供了強(qiáng)大的原生支持,本文討論Go的高級(jí)并發(fā)模式,理解這些并發(fā)模式,可以幫助我們編寫高效的Go應(yīng)用程序,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02