This commit is contained in:
史悦
2025-08-13 19:03:20 +08:00
commit d62a2e9ed9
73 changed files with 7296 additions and 0 deletions

96
pkg/crypto/AES.go Normal file
View File

@@ -0,0 +1,96 @@
package crypto
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
)
//高级加密标准Adevanced Encryption Standard ,AES
//key不能泄露
//PKCS7Padding PKCS7 填充模式
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
//Repeat()函数的功能是把切片[]byte{byte(padding)}复制padding个然后合并成新的字节切片返回
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
//PKCS7UnPadding 填充的反向操作,删除填充字符串
func PKCS7UnPadding(origData []byte) ([]byte, error) {
//获取数据长度
length := len(origData)
if length == 0 {
return nil, errors.New("加密字符串错误!")
} else {
//获取填充字符串长度
unpadding := int(origData[length-1])
//截取切片,删除填充字节,并且返回明文
return origData[:(length - unpadding)], nil
}
}
//AesEcrypt 实现加密
func AesEcrypt(origData []byte, key []byte) ([]byte, error) {
//创建加密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//获取块的大小
blockSize := block.BlockSize()
//对数据进行填充,让数据长度满足需求
origData = PKCS7Padding(origData, blockSize)
//采用AES加密方法中CBC加密模式
blocMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
//执行加密
blocMode.CryptBlocks(crypted, origData)
return crypted, nil
}
//AesDeCrypt 实现解密
func AesDeCrypt(cypted []byte, key []byte) ([]byte, error) {
//创建加密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//获取块大小
blockSize := block.BlockSize()
//创建加密客户端实例
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(cypted))
//这个函数也可以用来解密
blockMode.CryptBlocks(origData, cypted)
//去除填充字符串
origData, err = PKCS7UnPadding(origData)
if err != nil {
return nil, err
}
return origData, err
}
//EnPwdCode 加密base64
func EnPwdCode(pwd, PwdKey []byte) (string, error) {
result, err := AesEcrypt(pwd, PwdKey)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(result), err
}
//DePwdCode 解密
func DePwdCode(pwd string, PwdKey []byte) ([]byte, error) {
//解密base64字符串
pwdByte, err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return nil, err
}
//执行AES解密
return AesDeCrypt(pwdByte, PwdKey)
}

16
pkg/crypto/md5.go Normal file
View File

@@ -0,0 +1,16 @@
package crypto
import (
"crypto/md5"
"encoding/hex"
)
//GetMd5 生成32位md5字串
func GetMd5(s string) string {
if s == "" {
return ""
}
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}

104
pkg/crypto/sing.go Normal file
View File

@@ -0,0 +1,104 @@
package crypto
import (
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"math/rand"
"reflect"
"sort"
"strconv"
"time"
)
// GetSign get the sign info
func GetSign(data interface{}, appSecret string) string {
md5ctx := md5.New()
switch v := reflect.ValueOf(data); v.Kind() {
case reflect.String:
md5ctx.Write([]byte(v.String() + appSecret))
return hex.EncodeToString(md5ctx.Sum(nil))
case reflect.Struct:
orderStr := StructToMapSing(v.Interface(), appSecret)
md5ctx.Write([]byte(orderStr))
return hex.EncodeToString(md5ctx.Sum(nil))
case reflect.Ptr:
originType := v.Elem().Type()
if originType.Kind() != reflect.Struct {
return ""
}
dataType := reflect.TypeOf(data).Elem()
dataVal := v.Elem()
orderStr := buildOrderStr(dataType, dataVal, appSecret)
md5ctx.Write([]byte(orderStr))
return hex.EncodeToString(md5ctx.Sum(nil))
default:
return ""
}
}
func buildOrderStr(t reflect.Type, v reflect.Value, appSecret string) (returnStr string) {
keys := make([]string, 0, t.NumField())
var data = make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
if t.Field(i).Tag.Get("json") == "sign" {
continue
}
data[t.Field(i).Tag.Get("json")] = v.Field(i).Interface()
keys = append(keys, t.Field(i).Tag.Get("json"))
}
sort.Sort(sort.StringSlice(keys))
var buf bytes.Buffer
for _, k := range keys {
if data[k] == "" {
continue
}
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(k)
buf.WriteByte('=')
switch vv := data[k].(type) {
case string:
buf.WriteString(vv)
case int:
case int8:
case int16:
case int32:
case int64:
buf.WriteString(strconv.FormatInt(int64(vv), 10))
default:
continue
}
}
buf.WriteString("&secret=" + appSecret)
returnStr = buf.String()
return returnStr
}
func StructToMapSing(content interface{}, appSecret string) (returnStr string) {
t := reflect.TypeOf(content)
v := reflect.ValueOf(content)
returnStr = buildOrderStr(t, v, appSecret)
return returnStr
}
func EnSign(query, body, key string) string {
//加密算法
//r随机数
//t时间戳
//qquery参数md5
//bBody参数md5
//k密钥
//组合成 k=%s&r=%d&t=%d&q=%s&b=%s
//进行md5
//最后组合成 r,t,md5
rand.Seed(time.Now().Unix())
r := rand.Intn(800000) + 100000
t := time.Now().Unix()
str := fmt.Sprintf("k=%s&r=%d&t=%d&q=%s&b=%s", key, r, t, GetMd5(query), GetMd5(body))
return fmt.Sprintf("%d,%d,%s", r, t, GetSign(str, key))
}