package crypt import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/hmac" "crypto/md5" "crypto/rand" "crypto/sha1" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "errors" "fmt" "hash/crc32" "io" "net/url" "os" "reflect" "sort" "strconv" "strings" "github.com/dgrijalva/jwt-go" ) // CreateToken 生成Token算法 func CreateToken(secret string, tokenClaims map[string]interface{}) (tokeness string, err error) { if secret == "" { return "", errors.New("secret is empty") } claims := jwt.MapClaims(tokenClaims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokeness, err = token.SignedString([]byte(secret)) if err != nil { return "", err } return tokeness, nil } func keyFunc(secret string) jwt.Keyfunc { return func(token *jwt.Token) (interface{}, error) { return []byte(secret), nil } } // ParseToken 解析Token func ParseToken(secret string, tokeness string) (map[string]interface{}, error) { if secret == "" || tokeness == "" { return nil, errors.New("secret or tokeness is empty") } token, err := jwt.Parse(tokeness, keyFunc(secret)) if err != nil { return nil, err } //验证token,如果token被修改过则为false if !token.Valid { return nil, errors.New("token is invalid") } claimsToken, ok := token.Claims.(jwt.MapClaims) if !ok { return nil, errors.New("cannot convert claim to MapClaim") } return claimsToken, nil } // StructToStr 结构体转json 先对结构体按照字典顺序排序 并返回字符串 func StructToStr(obj interface{}) (string, error) { if obj == nil { return "", errors.New("obj is not nil") } data := make(map[string]interface{}) bytes, err := json.Marshal(obj) if err != nil { return "", err } err = json.Unmarshal(bytes, &data) if err != nil { return "", err } str, err := MapToStr(data) if err != nil { return "", err } return str, nil } // MapToStr 对map按照字典顺序排序 并返回字符串 func MapToStr(data map[string]interface{}) (string, error) { if data == nil || len(data) == 0 { return "", errors.New("data is nil or empty") } newData := make(map[string]interface{}) keys := make([]string, 0, len(data)) for k := range data { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { newData[k] = data[k] } b, err := json.Marshal(newData) if err != nil { return "", err } str := string(b) return str, nil } // JSON2Struct json转struct func JSON2Struct(str string, obj interface{}) { if err := json.Unmarshal([]byte(str), &obj); err != nil { return } } // JSONArray2Struct json转struct func JSONArray2Struct(str []string, obj interface{}) []interface{} { var data []interface{} for _, v := range str { JSON2Struct(v, &obj) data = append(data, obj) } return data } // JSON2Map json转map func JSON2Map(str string) (map[string]interface{}, error) { var mapResult map[string]interface{} if err := json.Unmarshal([]byte(str), &mapResult); err != nil { return nil, err } return mapResult, nil } // StructToStrNormal 结构体转str func StructToStrNormal(obj interface{}) (string, error) { str, err := json.Marshal(obj) if err != nil { return "", err } return string(str), nil } func UrlValueToStr(values url.Values, exclude string) (string, string) { if values == nil { return "", "" } var buf bytes.Buffer var sign string keys := make([]string, 0, len(values)) for k, _ := range values { if k == exclude { sign = strings.Join(values[k], "") continue } keys = append(keys, k) } sort.Strings(keys) for i, k := range keys { if i != 0 { buf.WriteString("&") } buf.WriteString(k) buf.WriteString("=") buf.WriteString(strings.Join(values[k], "")) } return buf.String(), sign } // 对参数进行排序后 拼接成url字符串 只对一级字符串类型的参数做处理 func MapToUrlOnlyStr(data map[string]interface{}) string { if data == nil || len(data) == 0 { return "" } var buf bytes.Buffer keys := make([]string, 0, len(data)) for k := range data { keys = append(keys, k) } sort.Strings(keys) for i, k := range keys { if i != 0 { buf.WriteString("&") } buf.WriteString(k) buf.WriteString("=") if v, ok := data[k].(string); ok { buf.WriteString(v) } } return buf.String() } // MapToStr 对map按照字典顺序排序 并返回字符串url 拼接的字段 func MapToUrlStr(data map[string]interface{}) string { if data == nil || len(data) == 0 { return "" } var buf bytes.Buffer keys := make([]string, 0, len(data)) for k := range data { keys = append(keys, k) } sort.Strings(keys) for i, k := range keys { if i != 0 { buf.WriteString("&") } buf.WriteString(k) buf.WriteString("=") if v, ok := data[k].(string); ok { buf.WriteString(v) } else { t := reflect.TypeOf(data[k]) if t != nil && t.Kind() == reflect.Map { if v, ok := data[k].(map[string]interface{}); ok { buf.WriteString("{") str := MapToUrlStr(v) buf.WriteString(str) buf.WriteString("}") } } if t != nil && (t.Kind() == reflect.Slice || t.Kind() == reflect.Array) { arraybyte, _ := json.Marshal(data[k]) buf.WriteString(string(arraybyte)) } } } return buf.String() } // MapToURL 集合转URL func MapToURL(m map[string]string) string { if m == nil || len(m) == 0 { return "" } v := url.Values{} for k := range m { v.Set(k, string(m[k])) } return v.Encode() } func Strcut2UrlValue(obj interface{}) (string, error) { t := reflect.TypeOf(obj) v := reflect.ValueOf(obj) if t.Kind() != reflect.Struct { return "", errors.New("obj must be struct type") } u := url.Values{} for i := 0; i < t.NumField(); i++ { var value string tag := t.Field(i).Tag.Get("json") switch t.Field(i).Type.Kind() { case reflect.String: value = v.Field(i).String() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: value = strconv.Itoa(int(v.Field(i).Int())) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: value = strconv.FormatUint(v.Field(i).Uint(), 10) case reflect.Slice, reflect.Array: buf := bytes.Buffer{} b, _ := json.Marshal(v.Field(i).Interface()) t := strings.TrimRight(strings.TrimLeft(string(b), "["), "]") array := strings.Split(t, ",") if len(array) == 0 { value = "" } if len(array) == 1 { value = array[0] } else { for i, v := range array { if i == 0 { buf.WriteString(v) continue } buf.WriteString("&") buf.WriteString(tag) buf.WriteString("=") buf.WriteString(v) value = buf.String() } } } u.Add(tag, value) } dcodeurl, err := url.QueryUnescape(u.Encode()) return dcodeurl, err } // StrToMd5 字符串转md5 func StrToMd5(str string) string { data := []byte(str) return ByteToMd5(data) } // ByteToMd5 数组转md5 func ByteToMd5(data []byte) string { md5Ctx := md5.New() md5Ctx.Write(data) cipherStr := md5Ctx.Sum(nil) return hex.EncodeToString(cipherStr) } // FileToMd5 文件转MD5 func FileToMd5(fileName string) string { file, err := os.Open(fileName) if err != nil { return "" } defer file.Close() md5Ctx := md5.New() if _, err := io.Copy(md5Ctx, file); err != nil { return "" } cipherStr := md5Ctx.Sum(nil) return hex.EncodeToString(cipherStr) } // HashCode 对一个字符串生成唯一的hasHcode 码 func HashCode(src string) int { v := int(crc32.ChecksumIEEE([]byte(src))) if v > 0 { return v } if -v > 0 { return -v } return 0 } // HexToString converts func HexToString(data []byte) string { return hex.EncodeToString(data) } // StrToSha256 字符串转sha256 func StrToSha256(str string) string { shaCtx := sha256.New() shaCtx.Write([]byte(str)) shaBytes := shaCtx.Sum(nil) cipherStr := hex.EncodeToString(shaBytes[:]) return cipherStr } // StrToSha1 字符串转sha1 func StrToSha1(str string, secret string) []byte { h := hmac.New(sha1.New, []byte(secret)) h.Write([]byte(str)) return h.Sum(nil) } // StrToSha1 字符串转sha1 转16进制后 func StrToHmacSha1(str, secret string) string { return hex.EncodeToString(StrToSha1(str, secret)) } // StrToHmacSha256 加密 字符串转sha256加密字符串 func StrToHmacSha256(str string, secret string) string { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(str)) cipherStr := hex.EncodeToString(h.Sum(nil)) return cipherStr } func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS7UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } // AesEncrypt AES加密 func AesEncrypt(origData, key string) ([]byte, error) { origDataByte := []byte(origData) return CoreAesEncrypt(origDataByte, key) } // AesDecrypt AES解密 func AesDecrypt(crypted, key string) (string, error) { cryptedByte := []byte(crypted) return CoreAesDecrypt(cryptedByte, key) } // AesDecrypt AES解密 func AesDecryptByte(cryptedByte []byte, key string) (string, error) { return CoreAesDecrypt(cryptedByte, key) } // CoreAesEncrypt AES加密 func CoreAesEncrypt(origData []byte, key string) ([]byte, error) { keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return nil, err } blockSize := block.BlockSize() origData = PKCS7Padding(origData, blockSize) blockMode := cipher.NewCBCEncrypter(block, keybyte[:blockSize]) crypted := make([]byte, len(origData)) blockMode.CryptBlocks(crypted, origData) return crypted, nil } // CoreAesDecrypt AES解密 func CoreAesDecrypt(crypted []byte, key string) (string, error) { keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, keybyte[:blockSize]) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS7UnPadding(origData) return string(origData), nil } // XorEnc func XorEnc(src string, xorKey string) string { var result string j := 0 bt := []rune(src) xor := []rune(xorKey) for i := 0; i < len(bt); i++ { s := strconv.FormatInt(int64(bt[i]^xor[j]), 10) result = result + s j = 1 % len(xor) } return result } // XorDec func XorDec(src string, xorKey string) string { var result string j := 0 bt := []rune(src) xor := []rune(xorKey) for i := 0; i < len(bt); i++ { s := strconv.FormatInt(int64(bt[i]^xor[j]), 10) result = result + s j = i % len(xor) } return result } func XorDecode(src, key string) string { srcByte, _ := base64.StdEncoding.DecodeString(src) keyByte, _ := base64.StdEncoding.DecodeString(key) srcByte = xor(srcByte, keyByte) return base64.StdEncoding.EncodeToString(srcByte) } func XorEncode(src, key string) string { return XorDecode(src, key) } func xor(src []byte, key []byte) []byte { for i := 0; i < len(src); i++ { src[i] ^= key[i%len(key)] } return src } func XORLength(src []byte, key []byte, length int) []byte { for i := 0; i < length; i++ { src[i] ^= key[i%len(key)] } return src[:length] } // https://core.telegram.org/api/end-to-end#sending-and-receiving-messages-in-a-secret-chat func CoreAesEncryptEx(plain []byte, nonceLen int, key string) ([]byte, error) { nonce := make([]byte, nonceLen) _, err := io.ReadFull(rand.Reader, nonce) if err != nil { return nil, err } var largeShaRaw []byte largeShaRaw = append(largeShaRaw, []byte(key)...) largeShaRaw = append(largeShaRaw, nonce...) largeShaRawMid := len(largeShaRaw) / 2 msgKeyLarge := sha256.Sum256(largeShaRaw) msgKey := msgKeyLarge[8:24] //16 bytes var shaRawA []byte shaRawA = append(shaRawA, msgKey...) shaRawA = append(shaRawA, largeShaRaw[:largeShaRawMid]...) sha256a := sha256.Sum256(shaRawA) //32 bytes var shaRawB []byte shaRawB = append(shaRawB, largeShaRaw[largeShaRawMid:]...) shaRawB = append(shaRawB, msgKey...) sha256b := sha256.Sum256(shaRawB) //32 bytes var aesKey []byte //32 bytes AES-256 aesKey = append(aesKey, sha256a[:8]...) //a: 8 bytes aesKey = append(aesKey, sha256b[8:24]...) //b: 16 bytes aesKey = append(aesKey, sha256a[24:32]...) //a: 8 bytes var aesIV []byte // 16 bytes aesIV = append(aesIV, sha256b[:4]...) //b: 4 bytes aesIV = append(aesIV, sha256a[12:20]...) //a: 8 bytes aesIV = append(aesIV, sha256b[28:]...) //b: 4 bytes block, err := aes.NewCipher(aesKey) if err != nil { return nil, err } blockSize := block.BlockSize() ciphertext := PKCS7Padding(plain, blockSize) mode := cipher.NewCBCEncrypter(block, aesIV) cipher := make([]byte, nonceLen+len(ciphertext)) copy(cipher, nonce) mode.CryptBlocks(cipher[nonceLen:], ciphertext) return cipher, nil } func CoreAesDecryptEx(crypt []byte, nonceLen int, key string) ([]byte, error) { nonce := make([]byte, nonceLen) copy(nonce, crypt) var largeShaRaw []byte largeShaRaw = append(largeShaRaw, []byte(key)...) largeShaRaw = append(largeShaRaw, nonce...) largeShaRawMid := len(largeShaRaw) / 2 msgKeyLarge := sha256.Sum256(largeShaRaw) msgKey := msgKeyLarge[8:24] //16 bytes var shaRawA []byte shaRawA = append(shaRawA, msgKey...) shaRawA = append(shaRawA, largeShaRaw[:largeShaRawMid]...) sha256a := sha256.Sum256(shaRawA) //32 bytes var shaRawB []byte shaRawB = append(shaRawB, largeShaRaw[largeShaRawMid:]...) shaRawB = append(shaRawB, msgKey...) sha256b := sha256.Sum256(shaRawB) //32 bytes var aesKey []byte //32 bytes AES-256 aesKey = append(aesKey, sha256a[:8]...) //a: 8 bytes aesKey = append(aesKey, sha256b[8:24]...) //b: 16 bytes aesKey = append(aesKey, sha256a[24:32]...) //a: 8 bytes var aesIV []byte // 16 bytes aesIV = append(aesIV, sha256b[:4]...) //b: 4 bytes aesIV = append(aesIV, sha256a[12:20]...) //a: 8 bytes aesIV = append(aesIV, sha256b[28:]...) //b: 4 bytes block, err := aes.NewCipher(aesKey) if err != nil { return nil, err } realData := crypt[nonceLen:] blockMode := cipher.NewCBCDecrypter(block, aesIV) origData := make([]byte, len(realData)) blockMode.CryptBlocks(origData, realData) return PKCS7UnPadding(origData), nil } // base64补全 func padding(origin string) string { missing := len(origin) % 4 if missing != 0 { origin += strings.Repeat("=", 4-missing) } return origin } // AdDecrypt 集团广告中心-广告数据解密专用 func AdDecrypt(encryptedData, keyBase64 string) (res string, err error) { // 1. Base64 解码获取密钥 keyBytes, err := base64.StdEncoding.DecodeString(padding(keyBase64)) if err != nil { return "", fmt.Errorf("密钥 Base64 解码失败: %v", err) } // 2. Base64 解码获取加密数据 data, err := base64.StdEncoding.DecodeString(padding(encryptedData)) if err != nil { return "", fmt.Errorf("数据 Base64 解码失败: %v", err) } // 3. 拆分 IV 与密文(前 12 字节为 IV) if len(data) < 12 { return "", errors.New("数据长度不足,无法提取 IV") } iv := data[:12] ciphertext := data[12:] // 4. 初始化 AES 密码块 block, err := aes.NewCipher(keyBytes) if err != nil { return "", fmt.Errorf("创建 AES 密码块失败: %v", err) } // 5. 采用 GCM 模式 aesGCM, err := cipher.NewGCM(block) if err != nil { return "", fmt.Errorf("创建 GCM 失败: %v", err) } // 6. 解密数据 plainText, err := aesGCM.Open(nil, iv, ciphertext, nil) if err != nil { return "", fmt.Errorf("解密失败: %v", err) } return string(plainText), nil }