Files
ag_toolsbox/encryption/spiral/spiral.go

94 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 提供自定义的随机密钥自解密加密算法支持算法代号Spiral。
package spiral
import (
"crypto/aes"
"crypto/cipher"
"errors"
"fmt"
"strings"
"archgrid.xyz/ag/toolsbox/encryption"
"archgrid.xyz/ag/toolsbox/hash/sha512"
verifyCode "archgrid.xyz/ag/toolsbox/random/verify_code"
"archgrid.xyz/ag/toolsbox/serialize/base64"
)
type Strength int
const (
Compatible Strength = iota
Enhanced
)
// 根据给定的密钥字符串生成加解密使用的密钥。
// 与Rust版本兼容使用SHA512 hex字符串的字节表示。
func generateKey(key string) []byte {
hexStr := sha512.Sha512Hex([]byte(key))
// 取hex字符串的第4-36字节对应Rust版本
return []byte(hexStr[4:36])
}
// 对给定的数据进行加密。
func Encrypt(data string, strength ...Strength) (string, error) {
key := verifyCode.RandStr(20)
keyBytes := generateKey(key)
// 直接使用crypto/aes避免二次SHA256哈希
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("创建加密单元失败,%w", err)
}
// 使用key的前16字节作为IV与Rust版本PrefixIVGenerator对应
iv := keyBytes[:16]
// PKCS7 padding
plainText := encryption.Padding([]byte(data), block.BlockSize(), encryption.PKCS7Padding)
cipherData := make([]byte, len(plainText))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(cipherData, plainText)
var result strings.Builder
result.WriteString("[")
result.WriteString(key)
result.WriteString(base64.ToBase64(cipherData))
return result.String(), nil
}
// 对给定的数据进行解密。
func Decrypt(data string, strength ...Strength) (string, error) {
if message, found := strings.CutPrefix(data, "["); found {
if len(message) > 20 {
keySeed := message[:20]
keyBytes := generateKey(keySeed)
cipherData, err := base64.FromBase64(message[20:])
if err != nil {
return "", fmt.Errorf("密文损坏无法解析,%w", err)
}
// 直接使用crypto/aes避免二次SHA256哈希
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("创建加密单元失败,%w", err)
}
// 使用key的前16字节作为IV与Rust版本对应
iv := keyBytes[:16]
plainText := make([]byte, len(cipherData))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plainText, cipherData)
// PKCS7 unpadding
plainText = encryption.Unpadding(plainText, encryption.PKCS7Padding)
return string(plainText), nil
}
return "", errors.New("密文缺损,无法完成解密。")
}
return data, nil
}