最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go使用SM3哈希算法和隨機鹽實現(xiàn)用戶密碼加密

 更新時間:2025年12月03日 09:02:49   作者:今天也很困  
在現(xiàn)代 Web 系統(tǒng)中,用戶密碼安全存儲是非常關(guān)鍵的一環(huán),本文將介紹如何使用 SM3 哈希算法 + 隨機鹽 (salt) 來加密用戶密碼,并提供 Go 語言實現(xiàn)示例,需要的朋友可以參考下

前言

在現(xiàn)代 Web 系統(tǒng)中,用戶密碼安全存儲是非常關(guān)鍵的一環(huán)。
傳統(tǒng)做法用簡單哈希,容易受到彩虹表攻擊。

本文將介紹如何使用 SM3 哈希算法 + 隨機鹽 (salt) 來加密用戶密碼,并提供 Go 語言實現(xiàn)示例。

一、為什么要加鹽 (Salt)

直接哈希密碼存在以下問題:

彩虹表攻擊

  • 攻擊者可以通過預(yù)先計算的哈希表快速破解常用密碼。

相同密碼哈希值相同

  • 用戶 A 和用戶 B 使用相同密碼,會生成相同哈希值,增加泄露風(fēng)險。

解決方案
在密碼哈希前增加隨機鹽 (Salt),每個用戶的密碼哈希值都不同,即使密碼相同也不會重復(fù)。

二、SM3 哈希算法

SM3 是中國國家標(biāo)準的哈希算法(國密算法),具有:

  • 輸出長度 256 位
  • 安全性高,適用于密碼存儲
  • 廣泛應(yīng)用于金融和安全系統(tǒng)

在 Go 中可以使用 github.com/tjfoc/gmsm/sm3 來實現(xiàn) SM3 哈希。

三、Go 實現(xiàn)用戶密碼加密

下面是一套完整的 SM3 密碼加密方案:

1. 生成隨機鹽

func generateSalt() (string, error) {
    b := make([]byte, 16) // 16字節(jié)隨機鹽
    if _, err := rand.Read(b); err != nil {
        return "", err
    }
    return hex.EncodeToString(b), nil
}
  • 使用 crypto/rand 生成安全隨機數(shù)
  • 轉(zhuǎn)為十六進制字符串存儲

2. SM3 哈希函數(shù)

func sm3Hash(password, salt string) string {
    h := sm3.New()
    h.Write([]byte(password + salt))
    return hex.EncodeToString(h.Sum(nil))
}
  • 將密碼和鹽拼接后進行 SM3 哈希
  • 返回十六進制字符串

3. 生成哈希密碼

func HashPassword(password string) (string, error) {
    salt, err := generateSalt()
    if err != nil {
        return "", err
    }
    hash := sm3Hash(password, salt)
    return fmt.Sprintf("sm3$v1$%s$%s", salt, hash), nil
}
  • 存儲格式為:sm3$v1$<salt_hex>$<hash_hex>
  • 包含算法標(biāo)識、版本、鹽和哈希值,便于版本升級和兼容不同算法

4. 驗證密碼

func CheckPassword(dbPassword, inputPassword string) (bool, error) {
    parts := strings.Split(dbPassword, "$")
    if len(parts) != 4 {
        return false, errors.New("hash 格式不正確")
    }
    _, version, salt, hash := parts[0], parts[1], parts[2], parts[3]
    if version != "v1" {
        return false, errors.New("不支持的版本")
    }
    calculatedHash := sm3Hash(inputPassword, salt)
    return calculatedHash == hash, nil
}
  • 從數(shù)據(jù)庫中取出存儲的哈希
  • 提取鹽和版本信息
  • 對輸入密碼進行同樣哈希并對比

5. 可擴展支持多種算法

代碼中還可以支持 bcrypt 或其他哈希算法:

func CheckPassword(dbPassword, inputPassword, hashAlgo string) (bool, error) {
    switch hashAlgo {
    case "bcrypt":
        return bcrypt.CompareHashAndPassword([]byte(dbPassword), []byte(inputPassword)) == nil, nil
    case "sm3":
        return CheckPassword(dbPassword, inputPassword)
    default:
        return false, errors.New("未知 hash 算法")
    }
}
  • 方便未來系統(tǒng)遷移或混合使用多種哈希方案

四、完整示例

func main() {
    password := "123456"
    
    hash, _ := HashPassword(password)
    fmt.Println("存儲密碼:", hash)
    
    ok, _ := CheckPassword(hash, password)
    fmt.Println("驗證密碼:", ok)
}

輸出示例:

存儲密碼: sm3$v1$e2a3f4...$9f8d7c...
驗證密碼: true

五、小結(jié)

  • 使用 SM3 + 隨機鹽,可以安全存儲用戶密碼
  • 存儲格式建議包含算法和版本號,便于升級
  • 密碼驗證時只需從數(shù)據(jù)庫取出鹽和哈希值即可
  • 結(jié)合 Go 的標(biāo)準庫和 gmsm/sm3,可以快速落地

使用 SM3 哈希和鹽的方式,能有效抵御彩虹表攻擊和密碼重復(fù)泄露風(fēng)險,是企業(yè)級系統(tǒng)密碼安全存儲的可靠方案。

到此這篇關(guān)于Go使用SM3哈希算法和隨機鹽實現(xiàn)用戶密碼加密的文章就介紹到這了,更多相關(guān)Go SM3哈希和隨機鹽實現(xiàn)密碼加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go設(shè)置http請求超時的方法實現(xiàn)

    Go設(shè)置http請求超時的方法實現(xiàn)

    這篇文章主要介紹了Go設(shè)置http請求超時的方法實現(xiàn),最近接手了一個老項目進行維護,發(fā)現(xiàn)其中有個關(guān)于 http 請求的方法設(shè)置的 timeout 沒有生效,很奇怪,一開始查看代碼并沒有發(fā)現(xiàn)什么可疑點,后查看了源碼,打斷點調(diào)試才發(fā)現(xiàn)問題所在,這里簡單記錄復(fù)盤一下
    2024-08-08
  • golang 定時任務(wù)方面time.Sleep和time.Tick的優(yōu)劣對比分析

    golang 定時任務(wù)方面time.Sleep和time.Tick的優(yōu)劣對比分析

    這篇文章主要介紹了golang 定時任務(wù)方面time.Sleep和time.Tick的優(yōu)劣對比分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • golang 如何通過反射創(chuàng)建新對象

    golang 如何通過反射創(chuàng)建新對象

    這篇文章主要介紹了golang 通過反射創(chuàng)建新對象的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言標(biāo)準庫sync.Once使用場景及性能優(yōu)化詳解

    Go語言標(biāo)準庫sync.Once使用場景及性能優(yōu)化詳解

    這篇文章主要為大家介紹了Go語言標(biāo)準庫sync.Once使用場景及性能優(yōu)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Go語言學(xué)習(xí)之鏈表的使用詳解

    Go語言學(xué)習(xí)之鏈表的使用詳解

    鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。本文將詳細為大家介紹Go語言中鏈表的使用,感興趣的可以了解一下
    2022-04-04
  • Go中的應(yīng)用配置管理詳解

    Go中的應(yīng)用配置管理詳解

    這篇文章主要為大家介紹了Go中的應(yīng)用配置管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Go Map并發(fā)沖突預(yù)防與解決

    Go Map并發(fā)沖突預(yù)防與解決

    這篇文章主要為大家介紹了Go Map并發(fā)沖突預(yù)防與解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Golang使用WebSocket通信的實現(xiàn)

    Golang使用WebSocket通信的實現(xiàn)

    這篇文章主要介紹了Golang使用WebSocket通信的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Go語言之fo循環(huán)與條件判斷

    Go語言之fo循環(huán)與條件判斷

    這篇文章主要介紹Go語言之fo循環(huán)與條件判斷,for 循環(huán)是一個循環(huán)控制結(jié)構(gòu),可以執(zhí)行指定次數(shù)的循環(huán)。下面文章我們結(jié)合條件判斷,感興趣的朋友可以參考一下
    2021-10-10
  • Go 備份數(shù)據(jù)庫表的實現(xiàn)示例

    Go 備份數(shù)據(jù)庫表的實現(xiàn)示例

    備份mysql數(shù)據(jù)庫的方法有很多,常用的可以登錄mysql活著使用mysqldump命令進行備份,本文提供golang的方式來備份mysql數(shù)據(jù)庫,下面就來詳細的介紹一下
    2026-06-06

最新評論

安多县| 临城县| 永登县| 阿城市| 吉林省| 锦屏县| 抚顺县| 壤塘县| 时尚| 宜城市| 建湖县| 临高县| 东光县| 上犹县| 海城市| 云南省| 集贤县| 邹城市| 临桂县| 北安市| 鄄城县| 南召县| 夏邑县| 清远市| 天全县| 安岳县| 马尔康县| 乌兰察布市| 南漳县| 和田县| 阿勒泰市| 淳安县| 杨浦区| 朝阳区| 图们市| 滦南县| 繁峙县| 彰化县| 高平市| 元江| 云阳县|