138 lines
3.3 KiB
Go
138 lines
3.3 KiB
Go
package crypt
|
|
|
|
import (
|
|
"91porn-server/common/log"
|
|
"91porn-server/web/webg"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net/url"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
//const appSecret = "iPEnB74mfCZhNNnY" //(客服后台->产品列表 对应产品的产品密钥) 测试
|
|
|
|
func CheckSign(sign string, data interface{}, router string) bool {
|
|
//对参数进行加密,和sign 进行对比
|
|
dataMap, _ := StructToMap(data, router)
|
|
params := url.Values{}
|
|
for k, v := range dataMap {
|
|
params.Set(k, v)
|
|
}
|
|
mySign, err := GenerateSign(params.Encode(), webg.Conf.Customer.Secret)
|
|
if err != nil {
|
|
log.Error("CheckSign Generate signature error:", log.Any("Secret", webg.Conf.Customer.Secret), log.E(err))
|
|
return false
|
|
}
|
|
return mySign == sign
|
|
}
|
|
|
|
// StructToMap 将结构体转换为map[string]string
|
|
func StructToMap(data interface{}, router string) (map[string]string, error) {
|
|
result := make(map[string]string)
|
|
|
|
// 使用反射获取结构体信息
|
|
v := reflect.ValueOf(data)
|
|
t := reflect.TypeOf(data)
|
|
|
|
// 如果是指针,获取指向的元素
|
|
if t.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
t = t.Elem()
|
|
}
|
|
|
|
// 确保是结构体类型
|
|
if t.Kind() != reflect.Struct {
|
|
return nil, fmt.Errorf("data must be a struct or pointer to struct")
|
|
}
|
|
|
|
// 遍历结构体字段
|
|
for i := 0; i < v.NumField(); i++ {
|
|
field := t.Field(i)
|
|
value := v.Field(i)
|
|
|
|
// 获取json标签作为key
|
|
jsonTag := field.Tag.Get("json")
|
|
if jsonTag == "" {
|
|
// 如果没有json标签,使用字段名
|
|
jsonTag = strings.ToLower(field.Name)
|
|
}
|
|
if router != "" {
|
|
if jsonTag == "appId" || jsonTag == "sign" {
|
|
continue
|
|
}
|
|
}
|
|
// 获取字段值并转换为字符串
|
|
var valueStr string
|
|
switch value.Kind() {
|
|
case reflect.String:
|
|
valueStr = value.String()
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
valueStr = fmt.Sprintf("%d", value.Int())
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
valueStr = fmt.Sprintf("%d", value.Uint())
|
|
case reflect.Bool:
|
|
valueStr = fmt.Sprintf("%t", value.Bool())
|
|
case reflect.Float32, reflect.Float64:
|
|
valueStr = fmt.Sprintf("%f", value.Float())
|
|
default:
|
|
valueStr = fmt.Sprintf("%v", value.Interface())
|
|
}
|
|
|
|
// 添加到结果中
|
|
result[jsonTag] = valueStr
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// PKCS7Padding PKCS7填充
|
|
func PKCS7Padding_1(data []byte, blockSize int) []byte {
|
|
padding := blockSize - len(data)%blockSize
|
|
padtext := make([]byte, padding)
|
|
for i := range padtext {
|
|
padtext[i] = byte(padding)
|
|
}
|
|
return append(data, padtext...)
|
|
}
|
|
|
|
// AESEncrypt AES-CBC加密
|
|
func AESEncrypt(origData, key []byte) ([]byte, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 使用密钥的前16字节作为IV
|
|
iv := key[:16]
|
|
|
|
// PKCS7填充
|
|
blockSize := block.BlockSize()
|
|
origData = PKCS7Padding_1(origData, blockSize)
|
|
|
|
// CBC模式加密
|
|
mode := cipher.NewCBCEncrypter(block, iv)
|
|
crypted := make([]byte, len(origData))
|
|
mode.CryptBlocks(crypted, origData)
|
|
|
|
return crypted, nil
|
|
}
|
|
|
|
// GenerateSign 生成签名
|
|
func GenerateSign(data, appSecret string) (string, error) {
|
|
key := []byte(appSecret)
|
|
plaintext := []byte(data)
|
|
|
|
ciphertext, err := AESEncrypt(plaintext, key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// 转换为十六进制字符串
|
|
hexStr := hex.EncodeToString(ciphertext)
|
|
|
|
return hexStr, nil
|
|
}
|