179 lines
5.0 KiB
Go
179 lines
5.0 KiB
Go
|
/**
|
||
|
* @Author: Echo
|
||
|
* @Author:1711788888@qq.com
|
||
|
* @Date: 2021/5/27 19:11
|
||
|
* @Desc: Transmission signature.
|
||
|
*/
|
||
|
|
||
|
package sign
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"compress/zlib"
|
||
|
"crypto/hmac"
|
||
|
"crypto/sha256"
|
||
|
"encoding/base64"
|
||
|
"encoding/json"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// GenUserSig gen a user sign.
|
||
|
func GenUserSig(sdkAppId int, key string, userid string, expire int) (string, error) {
|
||
|
return genUserSig(sdkAppId, key, userid, expire, nil)
|
||
|
}
|
||
|
|
||
|
// GenPrivateMapKey gen a private map.
|
||
|
func GenPrivateMapKey(sdkAppId int, key string, userid string, expire int, roomId uint32, privilegeMap uint32) (string, error) {
|
||
|
var userBuf []byte = genUserBuf(userid, sdkAppId, roomId, expire, privilegeMap, 0, "")
|
||
|
return genUserSig(sdkAppId, key, userid, expire, userBuf)
|
||
|
}
|
||
|
|
||
|
// GenPrivateMapKeyWithRoomId gen a private map with room id.
|
||
|
func GenPrivateMapKeyWithRoomId(sdkAppId int, key string, userid string, expire int, roomId string, privilegeMap uint32) (string, error) {
|
||
|
var userBuf []byte = genUserBuf(userid, sdkAppId, 0, expire, privilegeMap, 0, roomId)
|
||
|
return genUserSig(sdkAppId, key, userid, expire, userBuf)
|
||
|
}
|
||
|
|
||
|
// genUserBuf gen a user buffer.
|
||
|
func genUserBuf(account string, dwSdkappid int, dwAuthID uint32,
|
||
|
dwExpTime int, dwPrivilegeMap uint32, dwAccountType uint32, roomStr string) []byte {
|
||
|
|
||
|
offset := 0
|
||
|
length := 1 + 2 + len(account) + 20 + len(roomStr)
|
||
|
if len(roomStr) > 0 {
|
||
|
length = length + 2
|
||
|
}
|
||
|
|
||
|
userBuf := make([]byte, length)
|
||
|
|
||
|
// ver
|
||
|
if len(roomStr) > 0 {
|
||
|
userBuf[offset] = 1
|
||
|
} else {
|
||
|
userBuf[offset] = 0
|
||
|
}
|
||
|
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((len(account) & 0xFF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(len(account) & 0x00FF)
|
||
|
offset++
|
||
|
|
||
|
for ; offset < len(account)+3; offset++ {
|
||
|
userBuf[offset] = account[offset-3]
|
||
|
}
|
||
|
|
||
|
// dwSdkAppid
|
||
|
userBuf[offset] = (byte)((int64(dwSdkappid) & 0xFF000000) >> 24)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwSdkappid & 0x00FF0000) >> 16)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwSdkappid & 0x0000FF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(dwSdkappid & 0x000000FF)
|
||
|
offset++
|
||
|
|
||
|
// dwAuthId
|
||
|
userBuf[offset] = (byte)((dwAuthID & 0xFF000000) >> 24)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwAuthID & 0x00FF0000) >> 16)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwAuthID & 0x0000FF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(dwAuthID & 0x000000FF)
|
||
|
offset++
|
||
|
|
||
|
// dwExpTime now+300;
|
||
|
currTime := time.Now().Unix()
|
||
|
var expire = currTime + int64(dwExpTime)
|
||
|
userBuf[offset] = (byte)((expire & 0xFF000000) >> 24)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((expire & 0x00FF0000) >> 16)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((expire & 0x0000FF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(expire & 0x000000FF)
|
||
|
offset++
|
||
|
|
||
|
// dwPrivilegeMap
|
||
|
userBuf[offset] = (byte)((dwPrivilegeMap & 0xFF000000) >> 24)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwPrivilegeMap & 0x00FF0000) >> 16)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwPrivilegeMap & 0x0000FF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(dwPrivilegeMap & 0x000000FF)
|
||
|
offset++
|
||
|
|
||
|
// dwAccountType
|
||
|
userBuf[offset] = (byte)((dwAccountType & 0xFF000000) >> 24)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwAccountType & 0x00FF0000) >> 16)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)((dwAccountType & 0x0000FF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(dwAccountType & 0x000000FF)
|
||
|
offset++
|
||
|
|
||
|
if len(roomStr) > 0 {
|
||
|
userBuf[offset] = (byte)((len(roomStr) & 0xFF00) >> 8)
|
||
|
offset++
|
||
|
userBuf[offset] = (byte)(len(roomStr) & 0x00FF)
|
||
|
offset++
|
||
|
|
||
|
for ; offset < length; offset++ {
|
||
|
userBuf[offset] = roomStr[offset-(length-len(roomStr))]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return userBuf
|
||
|
}
|
||
|
|
||
|
// hmacSha256 encrypt with HMAC SHA256.
|
||
|
func hmacSha256(sdkAppId int, key string, identifier string, currTime int64, expire int, base64UserBuf *string) string {
|
||
|
var contentToBeSigned string
|
||
|
contentToBeSigned = "TLS.identifier:" + identifier + "\n"
|
||
|
contentToBeSigned += "TLS.sdkappid:" + strconv.Itoa(sdkAppId) + "\n"
|
||
|
contentToBeSigned += "TLS.time:" + strconv.FormatInt(currTime, 10) + "\n"
|
||
|
contentToBeSigned += "TLS.expire:" + strconv.Itoa(expire) + "\n"
|
||
|
if nil != base64UserBuf {
|
||
|
contentToBeSigned += "TLS.userbuf:" + *base64UserBuf + "\n"
|
||
|
}
|
||
|
|
||
|
h := hmac.New(sha256.New, []byte(key))
|
||
|
h.Write([]byte(contentToBeSigned))
|
||
|
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||
|
}
|
||
|
|
||
|
// genUserSig gen a sign
|
||
|
func genUserSig(sdkAppId int, key string, identifier string, expire int, userBuf []byte) (string, error) {
|
||
|
currTime := time.Now().Unix()
|
||
|
var sigDoc map[string]interface{}
|
||
|
sigDoc = make(map[string]interface{})
|
||
|
sigDoc["TLS.ver"] = "2.0"
|
||
|
sigDoc["TLS.identifier"] = identifier
|
||
|
sigDoc["TLS.sdkappid"] = sdkAppId
|
||
|
sigDoc["TLS.expire"] = expire
|
||
|
sigDoc["TLS.time"] = currTime
|
||
|
var base64UserBuf string
|
||
|
if nil != userBuf {
|
||
|
base64UserBuf = base64.StdEncoding.EncodeToString(userBuf)
|
||
|
sigDoc["TLS.userbuf"] = base64UserBuf
|
||
|
sigDoc["TLS.sig"] = hmacSha256(sdkAppId, key, identifier, currTime, expire, &base64UserBuf)
|
||
|
} else {
|
||
|
sigDoc["TLS.sig"] = hmacSha256(sdkAppId, key, identifier, currTime, expire, nil)
|
||
|
}
|
||
|
|
||
|
data, err := json.Marshal(sigDoc)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
var b bytes.Buffer
|
||
|
w := zlib.NewWriter(&b)
|
||
|
_, _ = w.Write(data)
|
||
|
_ = w.Close()
|
||
|
return base64Encode(b.Bytes()), nil
|
||
|
}
|