178 lines
4.0 KiB
Go
178 lines
4.0 KiB
Go
package algos
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/md5"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"math/rand"
|
|
"net/url"
|
|
)
|
|
|
|
// Argus Argus加密器
|
|
type Argus struct{}
|
|
|
|
// encryptEncPb 加密ProtoBuf
|
|
func encryptEncPb(data []byte, l int) []byte {
|
|
dataCopy := make([]byte, len(data))
|
|
copy(dataCopy, data)
|
|
|
|
xorArray := dataCopy[:8]
|
|
|
|
for i := 8; i < l; i++ {
|
|
dataCopy[i] ^= xorArray[i%8]
|
|
}
|
|
|
|
// 反转数组
|
|
for i := 0; i < l/2; i++ {
|
|
dataCopy[i], dataCopy[l-1-i] = dataCopy[l-1-i], dataCopy[i]
|
|
}
|
|
|
|
return dataCopy[:l]
|
|
}
|
|
|
|
// GetBodyHash 获取Body哈希
|
|
func GetBodyHash(stub string) []byte {
|
|
sm3 := NewSM3()
|
|
if stub == "" || len(stub) == 0 {
|
|
return sm3.Hash(make([]byte, 16))[0:6]
|
|
}
|
|
stubBytes, _ := hex.DecodeString(stub)
|
|
return sm3.Hash(stubBytes)[0:6]
|
|
}
|
|
|
|
// GetQueryHash 获取Query哈希
|
|
func GetQueryHash(query string) []byte {
|
|
sm3 := NewSM3()
|
|
if query == "" || len(query) == 0 {
|
|
return sm3.Hash(make([]byte, 16))[0:6]
|
|
}
|
|
return sm3.Hash([]byte(query))[0:6]
|
|
}
|
|
|
|
// Encrypt Argus加密
|
|
func (a *Argus) Encrypt(xargusBean map[int]interface{}) string {
|
|
// 创建ProtoBuf
|
|
protobuf := NewProtoBuf(xargusBean).ToBuf()
|
|
|
|
// PKCS7填充
|
|
protobuf = AddPKCS7Padding(protobuf, 16)
|
|
newLen := len(protobuf)
|
|
|
|
signKey := []byte{
|
|
0xAC, 0x1A, 0xDA, 0xAE, 0x95, 0xA7, 0xAF, 0x94,
|
|
0xA5, 0x11, 0x4A, 0xB3, 0xB3, 0xA9, 0x7D, 0xD8,
|
|
0x00, 0x50, 0xAA, 0x0A, 0x39, 0x31, 0x4C, 0x40,
|
|
0x52, 0x8C, 0xAE, 0xC9, 0x52, 0x56, 0xC2, 0x8C,
|
|
}
|
|
|
|
sm3Output := []byte{
|
|
0xFC, 0x78, 0xE0, 0xA9, 0x65, 0x7A, 0x0C, 0x74,
|
|
0x8C, 0xE5, 0x15, 0x59, 0x90, 0x3C, 0xCF, 0x03,
|
|
0x51, 0x0E, 0x51, 0xD3, 0xCF, 0xF2, 0x32, 0xD7,
|
|
0x13, 0x43, 0xE8, 0x8A, 0x32, 0x1C, 0x53, 0x04,
|
|
}
|
|
|
|
key := sm3Output[:32]
|
|
keyList := make([]uint64, 0)
|
|
encPb := make([]byte, newLen)
|
|
|
|
for i := 0; i < 2; i++ {
|
|
val1 := binary.LittleEndian.Uint64(key[i*16 : i*16+8])
|
|
val2 := binary.LittleEndian.Uint64(key[i*16+8 : i*16+16])
|
|
keyList = append(keyList, val1, val2)
|
|
}
|
|
|
|
for i := 0; i < newLen/16; i++ {
|
|
pt := []uint64{
|
|
binary.LittleEndian.Uint64(protobuf[i*16 : i*16+8]),
|
|
binary.LittleEndian.Uint64(protobuf[i*16+8 : i*16+16]),
|
|
}
|
|
ct := SimonEnc(pt, keyList, 0)
|
|
binary.LittleEndian.PutUint64(encPb[i*16:i*16+8], ct[0])
|
|
binary.LittleEndian.PutUint64(encPb[i*16+8:i*16+16], ct[1])
|
|
}
|
|
|
|
header := []byte{0xF2, 0xF7, 0xFC, 0xFF, 0xF2, 0xF7, 0xFC, 0xFF}
|
|
bBuffer := encryptEncPb(append(header, encPb...), newLen+8)
|
|
bBuffer = append([]byte{0xA6, 0x6E, 0xAD, 0x9F, 0x77, 0x01, 0xD0, 0x0C, 0x18}, bBuffer...)
|
|
bBuffer = append(bBuffer, []byte("ao")...)
|
|
|
|
// AES加密
|
|
keyHash := md5.Sum(signKey[:16])
|
|
ivHash := md5.Sum(signKey[16:])
|
|
|
|
block, _ := aes.NewCipher(keyHash[:])
|
|
paddedBuffer := AddPKCS7Padding(bBuffer, aes.BlockSize)
|
|
ciphertext := make([]byte, len(paddedBuffer))
|
|
|
|
mode := cipher.NewCBCEncrypter(block, ivHash[:])
|
|
mode.CryptBlocks(ciphertext, paddedBuffer)
|
|
|
|
result := append([]byte{0xF2, 0x81}, ciphertext...)
|
|
return base64.StdEncoding.EncodeToString(result)
|
|
}
|
|
|
|
// GetSign 获取签名
|
|
func (a *Argus) GetSign(
|
|
queryhash string,
|
|
data string,
|
|
timestamp int64,
|
|
aid int,
|
|
licenseID int,
|
|
platform int,
|
|
secDeviceID string,
|
|
sdkVersion string,
|
|
sdkVersionInt int,
|
|
) string {
|
|
paramsDict, _ := url.ParseQuery(queryhash)
|
|
|
|
deviceID := ""
|
|
if val, ok := paramsDict["device_id"]; ok && len(val) > 0 {
|
|
deviceID = val[0]
|
|
}
|
|
|
|
versionName := ""
|
|
if val, ok := paramsDict["version_name"]; ok && len(val) > 0 {
|
|
versionName = val[0]
|
|
}
|
|
|
|
xargusBean := map[int]interface{}{
|
|
1: 0x20200929 << 1,
|
|
2: 2,
|
|
3: rand.Int63n(0x7FFFFFFF),
|
|
4: fmt.Sprintf("%d", aid),
|
|
5: deviceID,
|
|
6: fmt.Sprintf("%d", licenseID),
|
|
7: versionName,
|
|
8: sdkVersion,
|
|
9: sdkVersionInt,
|
|
10: make([]byte, 8),
|
|
11: platform,
|
|
12: timestamp << 1,
|
|
13: GetBodyHash(data),
|
|
14: GetQueryHash(queryhash),
|
|
15: map[int]interface{}{
|
|
1: 1,
|
|
2: 1,
|
|
3: 1,
|
|
7: 3348294860,
|
|
},
|
|
16: secDeviceID,
|
|
20: "none",
|
|
21: 738,
|
|
23: map[int]interface{}{
|
|
1: "NX551J",
|
|
2: 8196,
|
|
4: 2162219008,
|
|
},
|
|
25: 2,
|
|
}
|
|
|
|
return a.Encrypt(xargusBean)
|
|
}
|
|
|