Files
go-utils/crypto/crypto.go
2025-05-07 13:52:07 +08:00

103 lines
2.4 KiB
Go

package crypto
import (
"fmt"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"golang.org/x/crypto/bcrypt"
)
// DefaultCost 最小值=4 最大值=31 默认值=10
var DefaultCost = 10
// HashPassword 加密密码
func HashPassword(password string) (string, error) {
// Prefix + Cost + Salt + Hashed Text
bytes, err := bcrypt.GenerateFromPassword([]byte(password), DefaultCost)
return string(bytes), err
}
// HashPasswordWithSalt 对密码进行加盐哈希处理
func HashPasswordWithSalt(password, salt string) (string, error) {
// 将密码和盐组合
combined := []byte(password + salt)
// 计算哈希值
hash := sha256.Sum256(combined)
// 将哈希值转换为十六进制字符串
return hex.EncodeToString(hash[:]), nil
}
// VerifyPassword 验证密码是否正确
func VerifyPassword(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
// VerifyPasswordWithSalt 验证密码是否正确
func VerifyPasswordWithSalt(password, salt, hashedPassword string) bool {
// 对输入的密码和盐进行哈希处理
newHash, _ := HashPasswordWithSalt(password, salt)
// 比较哈希值是否相同
return newHash == hashedPassword
}
// GenerateSalt 生成指定长度的盐
func GenerateSalt(length int) (string, error) {
salt := make([]byte, length)
_, err := rand.Read(salt)
if err != nil {
return "", err
}
return hex.EncodeToString(salt), nil
}
// DecryptAES AES解密函数
func DecryptAES(cipherText, key string) (string, error) {
// 将密文从Base64解码
cipherData, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
// 创建AES块
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
// 检查密文长度是否为块大小的倍数
if len(cipherData)%aes.BlockSize != 0 {
return "", fmt.Errorf("ciphertext is not a multiple of the block size")
}
// 创建CBC解密器
iv := cipherData[:aes.BlockSize] // 提取IV
cipherData = cipherData[aes.BlockSize:]
mode := cipher.NewCBCDecrypter(block, iv)
// 解密
plainText := make([]byte, len(cipherData))
mode.CryptBlocks(plainText, cipherData)
// 去除填充
plainText = pkcs7Unpad(plainText)
return string(plainText), nil
}
// pkcs7Unpad PKCS7填充去除
func pkcs7Unpad(data []byte) []byte {
length := len(data)
padding := int(data[length-1])
return data[:length-padding]
}