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 }