golang pbkdf2加密存储用户密码

    技术2022-07-11  87

    概述

    PBKDF2(Password-Based Key Derivation Function) 是一个用来导出密钥的函数,常用于生成加密的密码。原理是通过 password 和 salt 进行 hash 加密,然后将结果作为 salt 与 password 再进行 hash,多次重复此过程,生成最终的密文。如果重复的次数足够大(几千数万次),破解的成本就会变得很高。而盐值的添加也会增加“彩虹表”攻击的难度。

    用户密码采用PBKDF2算法存储,比较安全。

    代码

    package pbkdf2 import ( "crypto/rand" "crypto/sha256" "encoding/base64" mathrand "math/rand" "golang.org/x/crypto/pbkdf2" ) const ( saltMinLen = 8 saltMaxLen = 32 iter = 1000 keyLen = 32 ) // EncryptPwd 加密密码 func EncryptPwd(pwd string) (encrypt string, err error) { // 1、生成随机长度的盐值 salt, err := randSalt() if err != nil { return } // 2、生成加密串 en := encryptPwdWithSalt([]byte(pwd), salt) en = append(en, salt...) // 3、合并盐值 encrypt = base64.StdEncoding.EncodeToString(en) return } func randSalt() ([]byte, error) { // 生成8-32之间的随机数字 salt := make([]byte, mathrand.Intn(saltMaxLen-saltMinLen)+saltMinLen) _, err := rand.Read(salt) if err != nil { return nil, err } return salt, nil } func encryptPwdWithSalt(pwd, salt []byte) (pwdEn []byte) { pwd = append(pwd, salt...) pwdEn = pbkdf2.Key(pwd, salt, iter, keyLen, sha256.New) return } // CheckEncryptPwdMatch 验证密码是否与加密串匹配 func CheckEncryptPwdMatch(pwd, encrypt string) (ok bool) { // 1、参数校验 if len(encrypt) == 0 { return } enDecode, err := base64.StdEncoding.DecodeString(encrypt) if err != nil { return } // 2、截取加密串 固定长度 salt := enDecode[keyLen:] // 3、比对 enBase64 := base64.StdEncoding.EncodeToString(enDecode[0:keyLen]) pwdEnBase64 := base64.StdEncoding.EncodeToString(encryptPwdWithSalt([]byte(pwd), salt)) ok = enBase64 == pwdEnBase64 return }

    参考: 用户密码到底要怎么加密存储?

    Processed: 0.010, SQL: 9