mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
//go:build amd64
|
|
|
|
package t544
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"crypto/rc4"
|
|
"encoding/binary"
|
|
"math/rand"
|
|
|
|
"github.com/Mrs4s/go-cqhttp/internal/encryption"
|
|
)
|
|
|
|
const (
|
|
keyTable = "$%&()+,-456789:?ABCDEEFGHIJabcdefghijkopqrstuvwxyz"
|
|
table2 = "!#$%&)+.0123456789:=>?@ABCDEFGKMNabcdefghijkopqrst"
|
|
)
|
|
|
|
var (
|
|
magic = uint64(0x6EEDCF0DC4675540)
|
|
key1 = [8]byte{'a', '$', '(', 'e', 'T', '7', '*', '@'}
|
|
key2 = [8]byte{'&', 'O', '9', '!', '>', '6', 'X', ')'}
|
|
)
|
|
|
|
func init() {
|
|
encryption.T544Signer["8.9.35.10440"] = sign
|
|
encryption.T544Signer["8.9.38.10545"] = sign
|
|
}
|
|
|
|
// sign t544 algorithm
|
|
// special thanks to the anonymous contributor who provided the algorithm
|
|
func sign(curr int64, input []byte) []byte {
|
|
var crcData [0x15]byte
|
|
curr %= 1000000
|
|
binary.BigEndian.PutUint32(crcData[:4], uint32(curr))
|
|
input = append(input, crcData[:4]...)
|
|
var kt [4 + 32 + 4]byte
|
|
r := rand.New(rand.NewSource(curr))
|
|
for i := 0; i < 2; i++ {
|
|
kt[i] = keyTable[r.Int()%0x32] + 50
|
|
}
|
|
kt[2] = kt[1] + 20
|
|
kt[3] = kt[2] + 20
|
|
key3 := kt[4 : 4+10]
|
|
k3calc := key3[2:10]
|
|
copy(k3calc, key1[:4])
|
|
for i := 0; i < 4; i++ {
|
|
k3calc[4+i] = key2[i] ^ kt[i]
|
|
}
|
|
key3[0], key3[1] = k3calc[6], k3calc[7]
|
|
key3 = key3[:8]
|
|
k3calc[6], k3calc[7] = 0, 0
|
|
rc4Cipher, _ := rc4.NewCipher(key3)
|
|
rc4Cipher.XORKeyStream(key3, key3)
|
|
binary.LittleEndian.PutUint64(crcData[4:4+8], magic)
|
|
tencentEncryptionA(input, kt[4:4+32], crcData[4:4+8])
|
|
result := md5.Sum(input)
|
|
crcData[2] = 1
|
|
crcData[4] = 1
|
|
copy(crcData[5:9], kt[:4])
|
|
binary.BigEndian.PutUint32(crcData[9:13], uint32(curr))
|
|
copy(crcData[13:], result[:8])
|
|
calcCrc := tencentCrc32(&crc32Table, crcData[2:])
|
|
binary.LittleEndian.PutUint32(kt[4+32:4+32+4], calcCrc)
|
|
crcData[0] = kt[4+32]
|
|
crcData[1] = kt[4+32+3]
|
|
nonce := uint32(r.Int() ^ r.Int() ^ r.Int())
|
|
on := kt[:16]
|
|
binary.BigEndian.PutUint32(on[:4], nonce)
|
|
copy(on[4:8], on[:4])
|
|
copy(on[8:16], on[:8])
|
|
ts.transformEncode(&crcData)
|
|
encryptedData := crypto.tencentEncryptionB(on, crcData[:])
|
|
ts.transformDecode(&encryptedData)
|
|
output := kt[:39]
|
|
output[0] = 0x0C
|
|
output[1] = 0x05
|
|
binary.BigEndian.PutUint32(output[2:6], nonce)
|
|
copy(output[6:27], encryptedData[:])
|
|
binary.LittleEndian.PutUint32(output[27:31], 0)
|
|
output[31] = table2[r.Int()%0x32]
|
|
output[32] = table2[r.Int()%0x32]
|
|
addition := r.Int() % 9
|
|
for addition&1 == 0 {
|
|
addition = r.Int() % 9
|
|
}
|
|
output[33] = output[31] + byte(addition)
|
|
output[34] = output[32] + byte(9-addition) + 1
|
|
binary.LittleEndian.PutUint32(output[35:39], 0)
|
|
return output
|
|
}
|