372 lines
9.4 KiB
Go
372 lines
9.4 KiB
Go
package encryptx
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"code.yun.ink/pkg/encryptx/aesx"
|
|
"code.yun.ink/pkg/encryptx/base64x"
|
|
"code.yun.ink/pkg/encryptx/desx"
|
|
"code.yun.ink/pkg/encryptx/hmacx"
|
|
"code.yun.ink/pkg/encryptx/md5x"
|
|
"code.yun.ink/pkg/encryptx/pbkdf2x"
|
|
"code.yun.ink/pkg/encryptx/rsax"
|
|
"code.yun.ink/pkg/encryptx/sha1x"
|
|
"code.yun.ink/pkg/encryptx/sha256x"
|
|
"code.yun.ink/pkg/encryptx/sha3x"
|
|
"code.yun.ink/pkg/encryptx/sha512x"
|
|
"code.yun.ink/pkg/encryptx/tdesx"
|
|
"code.yun.ink/pkg/encryptx/utilsx"
|
|
)
|
|
|
|
// EncryptType 加密类型枚举
|
|
type EncryptType int
|
|
|
|
const (
|
|
// 哈希算法
|
|
MD5 EncryptType = iota
|
|
SHA1
|
|
SHA256
|
|
SHA512
|
|
SHA3_256
|
|
SHA3_384
|
|
SHA3_512
|
|
|
|
// 对称加密算法
|
|
DES_ECB
|
|
DES_CBC
|
|
DES_CFB
|
|
TDES_ECB
|
|
TDES_CBC
|
|
TDES_CFB
|
|
AES_ECB
|
|
AES_CBC
|
|
AES_CFB
|
|
AES_GCM
|
|
BLOWFISH_ECB
|
|
BLOWFISH_CBC
|
|
BLOWFISH_CFB
|
|
|
|
// 非对称加密算法
|
|
RSA
|
|
|
|
// 消息认证码
|
|
HMAC_SHA256
|
|
HMAC_SHA512
|
|
|
|
// 密钥派生
|
|
PBKDF2
|
|
|
|
// 编码
|
|
BASE64
|
|
)
|
|
|
|
var encryptTypeNames = map[EncryptType]string{
|
|
MD5: "MD5",
|
|
SHA1: "SHA1",
|
|
SHA256: "SHA256",
|
|
SHA512: "SHA512",
|
|
SHA3_256: "SHA3-256",
|
|
SHA3_384: "SHA3-384",
|
|
SHA3_512: "SHA3-512",
|
|
DES_ECB: "DES-ECB",
|
|
DES_CBC: "DES-CBC",
|
|
DES_CFB: "DES-CFB",
|
|
TDES_ECB: "3DES-ECB",
|
|
TDES_CBC: "3DES-CBC",
|
|
TDES_CFB: "3DES-CFB",
|
|
AES_ECB: "AES-ECB",
|
|
AES_CBC: "AES-CBC",
|
|
AES_CFB: "AES-CFB",
|
|
AES_GCM: "AES-GCM",
|
|
BLOWFISH_ECB: "Blowfish-ECB",
|
|
BLOWFISH_CBC: "Blowfish-CBC",
|
|
BLOWFISH_CFB: "Blowfish-CFB",
|
|
RSA: "RSA",
|
|
HMAC_SHA256: "HMAC-SHA256",
|
|
HMAC_SHA512: "HMAC-SHA512",
|
|
PBKDF2: "PBKDF2",
|
|
BASE64: "Base64",
|
|
}
|
|
|
|
// GetEncryptTypeName 获取加密类型的名称
|
|
func GetEncryptTypeName(encryptType EncryptType) string {
|
|
return encryptTypeNames[encryptType]
|
|
}
|
|
|
|
// GetAllEncryptTypes 获取所有加密类型
|
|
func GetAllEncryptTypes() []EncryptType {
|
|
types := make([]EncryptType, 0, len(encryptTypeNames))
|
|
for t := range encryptTypeNames {
|
|
types = append(types, t)
|
|
}
|
|
sort.Slice(types, func(i, j int) bool {
|
|
return int(types[i]) < int(types[j])
|
|
})
|
|
return types
|
|
}
|
|
|
|
// Encrypt 加密数据
|
|
// encryptType: 加密类型
|
|
// data: 要加密的数据
|
|
// key: 密钥(某些算法需要)
|
|
// options: 额外选项(如盐值、迭代次数等)
|
|
func Encrypt(encryptType EncryptType, data string, key string, options map[string]interface{}) (string, error) {
|
|
switch encryptType {
|
|
// 哈希算法
|
|
case MD5:
|
|
return md5x.Md5String(data), nil
|
|
case SHA1:
|
|
return sha1x.Sha1(data), nil
|
|
case SHA256:
|
|
return sha256x.Sha256(data), nil
|
|
case SHA512:
|
|
return sha512x.Sha512(data), nil
|
|
case SHA3_256:
|
|
return sha3x.Sha3_256(data), nil
|
|
case SHA3_384:
|
|
return sha3x.Sha3_384(data), nil
|
|
case SHA3_512:
|
|
return sha3x.Sha3_512(data), nil
|
|
|
|
// 对称加密算法
|
|
case DES_ECB:
|
|
return desx.EncryptECBHex(data, key)
|
|
case DES_CBC:
|
|
return desx.EncryptCBCHex(data, key)
|
|
case DES_CFB:
|
|
return desx.EncryptCFBHex(data, key)
|
|
case TDES_ECB:
|
|
return tdesx.EncryptECBHex(data, key)
|
|
case TDES_CBC:
|
|
return tdesx.EncryptCBCHex(data, key)
|
|
case TDES_CFB:
|
|
return tdesx.EncryptCFBHex(data, key)
|
|
case AES_ECB:
|
|
return aesx.EncryptECBHex(data, key)
|
|
case AES_CBC:
|
|
return aesx.EncryptCBCHex(data, key)
|
|
case AES_CFB:
|
|
return aesx.EncryptCFBHex(data, key)
|
|
case AES_GCM:
|
|
ciphertext, nonce, err := aesx.EncryptGCM(key, data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return ciphertext + ":" + nonce, nil
|
|
|
|
// 非对称加密算法
|
|
case RSA:
|
|
publicKeyPath, ok := options["publicKeyPath"].(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("RSA加密需要publicKeyPath选项")
|
|
}
|
|
cipherBytes := rsax.RSA_Encrypt([]byte(data), publicKeyPath)
|
|
return base64.StdEncoding.EncodeToString(cipherBytes), nil
|
|
|
|
// 消息认证码
|
|
case HMAC_SHA256:
|
|
return hmacx.HMACSHA256(data, key), nil
|
|
case HMAC_SHA512:
|
|
return hmacx.HMACSHA512(data, key), nil
|
|
|
|
// 密钥派生
|
|
case PBKDF2:
|
|
salt, ok := options["salt"].(string)
|
|
if !ok {
|
|
// 如果没有提供盐值,生成一个随机盐值
|
|
saltBytes := make([]byte, 16)
|
|
if _, err := rand.Read(saltBytes); err != nil {
|
|
return "", fmt.Errorf("生成随机盐值失败: %v", err)
|
|
}
|
|
salt = hex.EncodeToString(saltBytes)
|
|
}
|
|
|
|
iterations, ok := options["iterations"].(int)
|
|
if !ok {
|
|
iterations = 10000 // 默认迭代次数
|
|
}
|
|
|
|
keyLength, ok := options["keyLength"].(int)
|
|
if !ok {
|
|
keyLength = 32 // 默认密钥长度(32字节)
|
|
}
|
|
|
|
return pbkdf2x.DeriveKeyFromPassword(data, salt, iterations, keyLength)
|
|
|
|
// 编码
|
|
case BASE64:
|
|
return base64x.StdEncode(data), nil
|
|
|
|
default:
|
|
return "", fmt.Errorf("不支持的加密类型: %d", encryptType)
|
|
}
|
|
}
|
|
|
|
// Decrypt 解密数据
|
|
// encryptType: 加密类型
|
|
// data: 要解密的数据
|
|
// key: 密钥(某些算法需要)
|
|
// options: 额外选项(如盐值、迭代次数等)
|
|
func Decrypt(encryptType EncryptType, data string, key string, options map[string]interface{}) (string, error) {
|
|
switch encryptType {
|
|
// 哈希算法(不可逆)
|
|
case MD5, SHA1, SHA256, SHA512, SHA3_256, SHA3_384, SHA3_512:
|
|
return "", fmt.Errorf("哈希算法不可逆")
|
|
|
|
// 对称加密算法
|
|
case DES_ECB:
|
|
return desx.DecryptECBHex(data, key)
|
|
case DES_CBC:
|
|
return desx.DecryptCBCHex(data, key)
|
|
case DES_CFB:
|
|
return desx.DecryptCFBHex(data, key)
|
|
case TDES_ECB:
|
|
return tdesx.DecryptECBHex(data, key)
|
|
case TDES_CBC:
|
|
return tdesx.DecryptCBCHex(data, key)
|
|
case TDES_CFB:
|
|
return tdesx.DecryptCFBHex(data, key)
|
|
case AES_ECB:
|
|
return aesx.DecryptECBHex(data, key)
|
|
case AES_CBC:
|
|
return aesx.DecryptCBCHex(data, key)
|
|
case AES_CFB:
|
|
return aesx.DecryptCFBHex(data, key)
|
|
case AES_GCM:
|
|
parts := strings.Split(data, ":")
|
|
if len(parts) != 2 {
|
|
return "", fmt.Errorf("AES-GCM解密需要格式为'密文:nonce'")
|
|
}
|
|
return aesx.DecryptGCM(key, parts[0], parts[1])
|
|
|
|
// 非对称加密算法
|
|
case RSA:
|
|
privateKeyPath, ok := options["privateKeyPath"].(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("RSA解密需要privateKeyPath选项")
|
|
}
|
|
cipherBytes, err := base64.StdEncoding.DecodeString(data)
|
|
if err != nil {
|
|
return "", fmt.Errorf("Base64解码失败: %v", err)
|
|
}
|
|
plainBytes := rsax.RSA_Decrypt(cipherBytes, privateKeyPath)
|
|
return string(plainBytes), nil
|
|
|
|
// 消息认证码(不可逆)
|
|
case HMAC_SHA256, HMAC_SHA512:
|
|
return "", fmt.Errorf("消息认证码不可逆")
|
|
|
|
// 密钥派生(不可逆)
|
|
case PBKDF2:
|
|
return "", fmt.Errorf("密钥派生不可逆")
|
|
|
|
// 编码
|
|
case BASE64:
|
|
return base64x.StdDecode(data)
|
|
|
|
default:
|
|
return "", fmt.Errorf("不支持的加密类型: %d", encryptType)
|
|
}
|
|
}
|
|
|
|
// GenerateKey 生成密钥
|
|
// encryptType: 加密类型
|
|
// options: 额外选项
|
|
func GenerateKey(encryptType EncryptType, options map[string]interface{}) (string, error) {
|
|
switch encryptType {
|
|
// 哈希算法(不需要密钥)
|
|
case MD5, SHA1, SHA256, SHA512, SHA3_256, SHA3_384, SHA3_512:
|
|
return "", fmt.Errorf("哈希算法不需要密钥")
|
|
|
|
// 对称加密算法
|
|
case DES_ECB, DES_CBC, DES_CFB:
|
|
// DES密钥长度为8字节
|
|
keyBytes := make([]byte, 8)
|
|
if _, err := rand.Read(keyBytes); err != nil {
|
|
return "", fmt.Errorf("生成DES密钥失败: %v", err)
|
|
}
|
|
return hex.EncodeToString(keyBytes), nil
|
|
|
|
case TDES_ECB, TDES_CBC, TDES_CFB:
|
|
// 3DES密钥长度为24字节
|
|
keyBytes := make([]byte, 24)
|
|
if _, err := rand.Read(keyBytes); err != nil {
|
|
return "", fmt.Errorf("生成3DES密钥失败: %v", err)
|
|
}
|
|
return hex.EncodeToString(keyBytes), nil
|
|
|
|
case AES_ECB, AES_CBC, AES_CFB, AES_GCM:
|
|
// AES密钥长度为16、24或32字节
|
|
keyLength, ok := options["keyLength"].(int)
|
|
if !ok {
|
|
keyLength = 32 // 默认使用AES-256
|
|
}
|
|
if keyLength != 16 && keyLength != 24 && keyLength != 32 {
|
|
return "", fmt.Errorf("AES密钥长度必须为16、24或32字节")
|
|
}
|
|
keyBytes := make([]byte, keyLength)
|
|
if _, err := rand.Read(keyBytes); err != nil {
|
|
return "", fmt.Errorf("生成AES密钥失败: %v", err)
|
|
}
|
|
return hex.EncodeToString(keyBytes), nil
|
|
|
|
case BLOWFISH_ECB, BLOWFISH_CBC, BLOWFISH_CFB:
|
|
// Blowfish密钥长度可以是4-56字节
|
|
keyLength, ok := options["keyLength"].(int)
|
|
if !ok {
|
|
keyLength = 16 // 默认使用16字节
|
|
}
|
|
if keyLength < 4 || keyLength > 56 {
|
|
return "", fmt.Errorf("Blowfish密钥长度必须为4-56字节")
|
|
}
|
|
keyBytes := make([]byte, keyLength)
|
|
if _, err := rand.Read(keyBytes); err != nil {
|
|
return "", fmt.Errorf("生成Blowfish密钥失败: %v", err)
|
|
}
|
|
return hex.EncodeToString(keyBytes), nil
|
|
|
|
// 非对称加密算法
|
|
case RSA:
|
|
bits, ok := options["bits"].(int)
|
|
if !ok {
|
|
bits = 2048 // 默认使用2048位
|
|
}
|
|
rsax.GenerateRSAKey(bits)
|
|
return "RSA密钥已生成并保存到文件", nil
|
|
|
|
// 消息认证码
|
|
case HMAC_SHA256, HMAC_SHA512:
|
|
// HMAC密钥长度可以是任意值
|
|
keyLength, ok := options["keyLength"].(int)
|
|
if !ok {
|
|
keyLength = 32 // 默认使用32字节
|
|
}
|
|
keyBytes := make([]byte, keyLength)
|
|
if _, err := rand.Read(keyBytes); err != nil {
|
|
return "", fmt.Errorf("生成HMAC密钥失败: %v", err)
|
|
}
|
|
return hex.EncodeToString(keyBytes), nil
|
|
|
|
// 密钥派生
|
|
case PBKDF2:
|
|
// PBKDF2需要盐值
|
|
saltLength, ok := options["saltLength"].(int)
|
|
if !ok {
|
|
saltLength = 16 // 默认使用16字节盐值
|
|
}
|
|
return utilsx.GenerateRandomHexString(saltLength)
|
|
|
|
// 编码
|
|
case BASE64:
|
|
return "", fmt.Errorf("Base64编码不需要密钥")
|
|
|
|
default:
|
|
return "", fmt.Errorf("不支持的加密类型: %d", encryptType)
|
|
}
|
|
}
|