81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"server/internal/model"
|
|
)
|
|
|
|
// 内部常量,外部无法访问
|
|
const (
|
|
aesKey = "K8mN2pQ9rS5vX1zA" // 16字节密钥
|
|
aesIV = "H7jL4oP8qR6uW0yZ" // 16字节初始化向量
|
|
)
|
|
|
|
// DecryptAdsData 解密广告数据并反序列化
|
|
func DecryptAdsData(encryptedData string) (*model.AdsData, error) {
|
|
// 解码base64数据
|
|
ciphertext, err := base64.StdEncoding.DecodeString(encryptedData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("base64 decode failed: %v", err)
|
|
}
|
|
|
|
// 创建AES cipher
|
|
block, err := aes.NewCipher([]byte(aesKey))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("aes new cipher failed: %v", err)
|
|
}
|
|
|
|
// 检查数据长度
|
|
if len(ciphertext) < aes.BlockSize {
|
|
return nil, fmt.Errorf("ciphertext too short")
|
|
}
|
|
|
|
// 创建CBC模式
|
|
mode := cipher.NewCBCDecrypter(block, []byte(aesIV))
|
|
|
|
// 解密
|
|
plaintext := make([]byte, len(ciphertext))
|
|
mode.CryptBlocks(plaintext, ciphertext)
|
|
|
|
// 去除PKCS7填充
|
|
plaintext, err = pkcs7Unpad(plaintext)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("pkcs7 unpad failed: %v", err)
|
|
}
|
|
|
|
// 反序列化JSON
|
|
var adsData model.AdsData
|
|
err = json.Unmarshal(plaintext, &adsData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("json unmarshal failed: %v", err)
|
|
}
|
|
|
|
return &adsData, nil
|
|
}
|
|
|
|
// pkcs7Unpad 去除PKCS7填充
|
|
func pkcs7Unpad(data []byte) ([]byte, error) {
|
|
length := len(data)
|
|
if length == 0 {
|
|
return nil, fmt.Errorf("invalid padding")
|
|
}
|
|
|
|
padding := int(data[length-1])
|
|
if padding > length {
|
|
return nil, fmt.Errorf("invalid padding")
|
|
}
|
|
|
|
// 验证填充
|
|
for i := length - padding; i < length; i++ {
|
|
if data[i] != byte(padding) {
|
|
return nil, fmt.Errorf("invalid padding")
|
|
}
|
|
}
|
|
|
|
return data[:length-padding], nil
|
|
}
|