package pbkdf2x import ( "crypto/rand" "crypto/sha256" "encoding/hex" "fmt" "golang.org/x/crypto/pbkdf2" ) // GenerateSalt 生成随机盐值 func GenerateSalt(length int) (string, error) { if length <= 0 { return "", fmt.Errorf("盐值长度必须大于0") } salt := make([]byte, length) _, err := rand.Read(salt) if err != nil { return "", fmt.Errorf("生成盐值失败: %v", err) } return hex.EncodeToString(salt), nil } // DeriveKeyFromPassword 使用PBKDF2从密码派生密钥 // password: 原始密码 // saltHex: 十六进制格式的盐值 // iterations: 迭代次数,推荐至少10000次 // keyLength: 派生密钥的长度(字节) func DeriveKeyFromPassword(password, saltHex string, iterations, keyLength int) (string, error) { // 解码盐值 salt, err := hex.DecodeString(saltHex) if err != nil { return "", fmt.Errorf("盐值解码失败: %v", err) } // 使用PBKDF2派生密钥 key := pbkdf2.Key([]byte(password), salt, iterations, keyLength, sha256.New) // 返回十六进制格式的密钥 return hex.EncodeToString(key), nil } // DeriveKeyFromPasswordWithRandomSalt 使用PBKDF2从密码派生密钥,并自动生成随机盐值 // password: 原始密码 // saltLength: 盐值长度(字节) // iterations: 迭代次数,推荐至少10000次 // keyLength: 派生密钥的长度(字节) // 返回值: 密钥(十六进制), 盐值(十六进制), 错误 func DeriveKeyFromPasswordWithRandomSalt(password string, saltLength, iterations, keyLength int) (string, string, error) { // 生成随机盐值 saltHex, err := GenerateSalt(saltLength) if err != nil { return "", "", err } // 派生密钥 keyHex, err := DeriveKeyFromPassword(password, saltHex, iterations, keyLength) if err != nil { return "", "", err } return keyHex, saltHex, nil }