2019-01-28 03:19:49 +00:00
|
|
|
|
package utils
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"strings"
|
|
|
|
|
"log"
|
|
|
|
|
"time"
|
|
|
|
|
"fmt"
|
|
|
|
|
"encoding/pem"
|
|
|
|
|
"crypto/x509"
|
|
|
|
|
"crypto/rsa"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"errors"
|
|
|
|
|
"io"
|
|
|
|
|
"net/url"
|
|
|
|
|
"hash/crc32"
|
|
|
|
|
crand "crypto/rand"
|
|
|
|
|
"crypto/hmac"
|
|
|
|
|
"crypto/sha1"
|
|
|
|
|
"crypto/md5"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// md5
|
|
|
|
|
func Md5Sum(text string) string {
|
|
|
|
|
h := md5.New()
|
|
|
|
|
io.WriteString(h, text)
|
|
|
|
|
return fmt.Sprintf("%x", h.Sum(nil))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加解密函数 根据dz的Authcode改写的go版本
|
|
|
|
|
// params[0] 加密or解密 bool true:加密 false:解密 默认false
|
|
|
|
|
// params[1] 秘钥
|
|
|
|
|
// params[2] 加密:过期时间
|
|
|
|
|
// params[3] 动态秘钥长度 默认:4位 不能大于32位
|
|
|
|
|
func Authcode(text string, params ...interface{}) string {
|
|
|
|
|
defer func() {
|
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
log.Printf("authcode error:%#v", err)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
l := len(params)
|
|
|
|
|
|
|
|
|
|
isEncode := false
|
|
|
|
|
key := "DH-Framework"
|
|
|
|
|
expiry := 0
|
|
|
|
|
cKeyLen := 10
|
|
|
|
|
|
|
|
|
|
if l > 0 {
|
|
|
|
|
isEncode = params[0].(bool)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if l > 1 {
|
|
|
|
|
key = params[1].(string)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if l > 2 {
|
|
|
|
|
expiry = params[2].(int)
|
|
|
|
|
if expiry < 0 {
|
|
|
|
|
expiry = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if l > 3 {
|
|
|
|
|
cKeyLen = params[3].(int)
|
|
|
|
|
if cKeyLen < 0 {
|
|
|
|
|
cKeyLen = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if cKeyLen > 32 {
|
|
|
|
|
cKeyLen = 32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timestamp := time.Now().Unix()
|
|
|
|
|
|
|
|
|
|
// md5加密key
|
|
|
|
|
mKey := Md5Sum(key)
|
|
|
|
|
|
|
|
|
|
// 参与加密的
|
|
|
|
|
keyA := Md5Sum(mKey[0:16])
|
|
|
|
|
// 用于验证数据有效性的
|
|
|
|
|
keyB := Md5Sum(mKey[16:])
|
|
|
|
|
// 动态部分
|
|
|
|
|
var keyC string
|
|
|
|
|
if cKeyLen > 0 {
|
|
|
|
|
if isEncode {
|
|
|
|
|
// 加密的时候,动态获取一个秘钥
|
|
|
|
|
keyC = Md5Sum(fmt.Sprint(timestamp))[32 - cKeyLen:]
|
|
|
|
|
} else {
|
|
|
|
|
// 解密的时候从头部获取动态秘钥部分
|
|
|
|
|
keyC = text[0:cKeyLen]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加入了动态的秘钥
|
|
|
|
|
cryptKey := keyA + Md5Sum(keyA + keyC)
|
|
|
|
|
// 秘钥长度
|
|
|
|
|
keyLen := len(cryptKey)
|
|
|
|
|
if isEncode {
|
|
|
|
|
// 加密 前10位是过期验证字符串 10-26位字符串验证
|
|
|
|
|
var d int64
|
|
|
|
|
if expiry > 0 {
|
|
|
|
|
d = timestamp + int64(expiry)
|
|
|
|
|
}
|
|
|
|
|
text = fmt.Sprintf("%010d%s%s", d, Md5Sum(text + keyB)[0:16], text)
|
|
|
|
|
} else {
|
|
|
|
|
// 解密
|
|
|
|
|
text = string(Base64Decode(text[cKeyLen:]))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 字符串长度
|
|
|
|
|
textLen := len(text)
|
|
|
|
|
if textLen <= 0 {
|
|
|
|
|
panic(fmt.Sprintf("auth[%s]textLen<=0", text))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 密匙簿
|
|
|
|
|
box := Range(0, 256)
|
|
|
|
|
// 对称算法
|
|
|
|
|
var rndKey []int
|
|
|
|
|
cryptKeyB := []byte(cryptKey)
|
|
|
|
|
for i := 0; i < 256; i++ {
|
|
|
|
|
pos := i % keyLen
|
|
|
|
|
rndKey = append(rndKey, int(cryptKeyB[pos]))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j := 0
|
|
|
|
|
for i := 0; i < 256; i++ {
|
|
|
|
|
j = (j + box[i] + rndKey[i]) % 256
|
|
|
|
|
box[i], box[j] = box[j], box[i]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textB := []byte(text)
|
|
|
|
|
a := 0
|
|
|
|
|
j = 0
|
|
|
|
|
var result []byte
|
|
|
|
|
for i := 0; i < textLen; i++ {
|
|
|
|
|
a = (a + 1) % 256
|
|
|
|
|
j = (j + box[a]) % 256
|
|
|
|
|
box[a], box[j] = box[j], box[a]
|
|
|
|
|
result = append(result, byte(int(textB[i]) ^ (box[(box[a] + box[j]) % 256])))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if isEncode {
|
|
|
|
|
return keyC + strings.Replace(Base64Encode(result), "=", "", -1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取前10位,判断过期时间
|
|
|
|
|
d := Atoi64(string(result[0:10]), 0)
|
|
|
|
|
if (d == 0 || d - timestamp > 0) && string(result[10:26]) == Md5Sum(string(result[26:]) + keyB)[0:16] {
|
|
|
|
|
return string(result[26:])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(fmt.Sprintf("auth[%s]", text))
|
|
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AuthcodeUrl 处理Authcode函数的加密解密结果以便url传输
|
|
|
|
|
func AuthcodeUrl(text string, params ...interface{}) string {
|
|
|
|
|
isEncode := false
|
|
|
|
|
if len(params) > 0 {
|
|
|
|
|
isEncode = params[0].(bool)
|
|
|
|
|
}
|
|
|
|
|
if isEncode { //加密
|
|
|
|
|
return strings.Replace(strings.Replace(Authcode(text, params...), "+", ",", -1), "/", "-", -1)
|
|
|
|
|
} else {
|
|
|
|
|
return Authcode(strings.Replace(strings.Replace(text, ",", "+", -1), "-", "/", -1), params...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 08:57:22 +00:00
|
|
|
|
// JsonEncode 编码JSON
|
|
|
|
|
func JsonEncode(m interface{}) string {
|
2019-01-28 03:19:49 +00:00
|
|
|
|
b, err := json.Marshal(m)
|
|
|
|
|
if err != nil {
|
2019-01-31 08:57:22 +00:00
|
|
|
|
log.Printf("Json Encode[%#v] Error:%s", m, err.Error())
|
|
|
|
|
return ""
|
2019-01-28 03:19:49 +00:00
|
|
|
|
}
|
2019-01-31 08:57:22 +00:00
|
|
|
|
return string(b)
|
2019-01-28 03:19:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 08:57:22 +00:00
|
|
|
|
// JsonDecode 解码JSON
|
|
|
|
|
func JsonDecode(str string, v ...interface{}) (interface{}, error) {
|
2019-01-28 03:19:49 +00:00
|
|
|
|
var m interface{}
|
|
|
|
|
if len(v) > 0 {
|
|
|
|
|
m = v[0]
|
|
|
|
|
} else {
|
|
|
|
|
m = make(map[string]interface{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := json.Unmarshal([]byte(str), &m)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Crc32(text string) string {
|
|
|
|
|
h := crc32.NewIEEE()
|
|
|
|
|
io.WriteString(h, text)
|
|
|
|
|
return fmt.Sprintf("%d", h.Sum32())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RsaEncode rsa加密
|
|
|
|
|
func RsaEncode(b, rsaKey []byte) ([]byte, error) {
|
|
|
|
|
block, _ := pem.Decode(rsaKey)
|
|
|
|
|
if block == nil {
|
|
|
|
|
return b, errors.New("key error")
|
|
|
|
|
}
|
|
|
|
|
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return b, err
|
|
|
|
|
}
|
|
|
|
|
return rsa.EncryptPKCS1v15(crand.Reader, pub.(*rsa.PublicKey), b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RsaDecode rsa解密
|
|
|
|
|
func RsaDecode(b, rsaKey []byte) ([]byte, error) {
|
|
|
|
|
block, _ := pem.Decode(rsaKey)
|
|
|
|
|
if block == nil {
|
|
|
|
|
return b, errors.New("key error")
|
|
|
|
|
}
|
|
|
|
|
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return b, err
|
|
|
|
|
}
|
|
|
|
|
return rsa.DecryptPKCS1v15(crand.Reader, priv, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HashHmac(data, key string) string {
|
|
|
|
|
mac := hmac.New(sha1.New, []byte(key))
|
|
|
|
|
mac.Write([]byte(data))
|
|
|
|
|
return fmt.Sprintf("%x", mac.Sum(nil))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HashHmacRaw(data, key string) string {
|
|
|
|
|
mac := hmac.New(sha1.New, []byte(key))
|
|
|
|
|
mac.Write([]byte(data))
|
|
|
|
|
return fmt.Sprintf("%s", mac.Sum(nil))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Base64Encode Base64编码
|
|
|
|
|
func Base64Encode(b []byte) string {
|
|
|
|
|
return base64.StdEncoding.EncodeToString(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Base64Decode Base64解码
|
|
|
|
|
func Base64Decode(str string) []byte {
|
|
|
|
|
var b []byte
|
|
|
|
|
var err error
|
|
|
|
|
x := len(str) * 3 % 4
|
|
|
|
|
switch {
|
|
|
|
|
case x == 2:
|
|
|
|
|
str += "=="
|
|
|
|
|
case x == 1:
|
|
|
|
|
str += "="
|
|
|
|
|
}
|
|
|
|
|
if b, err = base64.StdEncoding.DecodeString(str); err != nil {
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UrlEncode 编码
|
|
|
|
|
func UrlEncode(str string) string {
|
|
|
|
|
return url.QueryEscape(str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UrlDecode 解码
|
|
|
|
|
func UrlDecode(str string) string {
|
|
|
|
|
ret, _ := url.QueryUnescape(str)
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*func Urlencode(str string) string {
|
|
|
|
|
return base64.URLEncoding.EncodeToString([]byte(str))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Urldecode(str string) string {
|
|
|
|
|
b, e := base64.URLEncoding.DecodeString(str)
|
|
|
|
|
if e != nil {
|
|
|
|
|
log.Printf("urldecode error:%s", e.Error())
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return string(b)
|
|
|
|
|
}*/
|