qqtea 加解密
<h2>se</h2>
<p>qqtea.go</p>
<pre><code>package se
import (
"fmt"
"math/rand"
"strconv"
"strings"
)
const delta = 0x9E3779B9
var SevenZeroByteStr string
func init() {
SevenZeroByteStr = string([]byte{0, 0, 0, 0, 0, 0, 0})
}
//加密
func Encrypt(data, key string) string {
FILL_N_OR := 0xF8
filln := (8 - (len(data) + 2)) % 8
if filln < 0 {
filln += 2 + 8
} else {
filln += 2
}
var fills []byte
for i := 0; i < filln; i++ {
fills = append(fills, byte(rand.Intn(255)))
}
_Data_buf := string([]byte{byte((filln - 2) | FILL_N_OR)}) + string(fills) + data + SevenZeroByteStr
tr := "\x00\x00\x00\x00\x00\x00\x00\x00"
to := tr
r := ""
o := tr
for i := 0; i < len(_Data_buf); i += 8 {
o = xor(_Data_buf[i:i+8], tr)
tr = xor(encipher(o, key, delta, 0x10), to)
to = o
r += tr
}
return r
}
//解密
func Decrypt(data, key string) string {
preCrypt := data[:8]
prePlain := decipher(preCrypt, key, delta, 0x10)
pos := (int64(prePlain[0]) & 0x7) + 2
r := prePlain
if len(data)%8 != 0 {
return ""
}
for i := 8; i < len(data); i += 8 {
x := xor(decipher(xor(data[i:i+8], prePlain), key, delta, 0x10), preCrypt)
prePlain = xor(x, preCrypt)
preCrypt = data[i : i+8]
r += x
}
s := bin2hex(r[len(r)-7:])
a1, _ := strconv.ParseInt(s, 16, 32)
if a1 != 0 {
return ""
}
pos++
return r[pos : len(r)-7]
}
func encipher(_Data string, _KEY string, _Delta int64, _Round int64) string {
_Delta_buf := _Delta
_Data_buf := stringToLongArray(_Data)
_KEY_buf := stringToLongArray(_KEY)
for _Round > 0 {
_Round--
_Data_buf[0] += ((_Data_buf[1] << 4 & 0xFFFFFFF0) + _KEY_buf[0]) ^ (_Data_buf[1] + _Delta_buf) ^ ((_Data_buf[1] >> 5 & 0x07FFFFFF) + _KEY_buf[1])
_Data_buf[1] += ((_Data_buf[0] << 4 & 0xFFFFFFF0) + _KEY_buf[2]) ^ (_Data_buf[0] + _Delta_buf) ^ ((_Data_buf[0] >> 5 & 0x07FFFFFF) + _KEY_buf[3])
_Delta_buf += _Delta
}
return longArrayToString(_Data_buf)
}
func decipher(_Data string, _KEY string, _Delta int64, _Round int64) string {
var _Delta_buf int64
//_Delta_buf = 3816266640
_Delta_buf = _Delta * _Round >> 0
_Data_buf := stringToLongArray(_Data)
_KEY_buf := stringToLongArray(_KEY)
for _Round > 0 {
_Round--
//_Data_buf[1] -= int64(int32(int64(int32(_Data_buf[0])<<4)&0xFFFFFFF0+_KEY_buf[2]) ^ int32(_Data_buf[0]+_Delta_buf) ^ int32(int64(int32(_Data_buf[0])>>5)&0x07FFFFFF+_KEY_buf[3]))
//_Data_buf[1] = int64(uint32(_Data_buf[1]) >> 0)
//_Data_buf[0] -= int64(int32(int64(int32(_Data_buf[1])<<4)&0xFFFFFFF0+_KEY_buf[0]) ^ int32(_Data_buf[1]+_Delta_buf) ^ int32(int64(int32(_Data_buf[1])>>5)&0x07FFFFFF+_KEY_buf[1]))
//_Data_buf[0] = int64(uint32(_Data_buf[0]) >> 0)
//_Delta_buf -= _Delta
_Data_buf[1] -= (_Data_buf[0]<<4&0xFFFFFFF0 + _KEY_buf[2]) ^ (_Data_buf[0] + _Delta_buf) ^ (_Data_buf[0]>>5&0x07FFFFFF + _KEY_buf[3])
_Data_buf[1] = (_Data_buf[1]) >> 0
_Data_buf[0] -= (_Data_buf[1]<<4&0xFFFFFFF0 + _KEY_buf[0]) ^ (_Data_buf[1] + _Delta_buf) ^ (_Data_buf[1]>>5&0x07FFFFFF + _KEY_buf[1])
_Data_buf[0] = (_Data_buf[0]) >> 0
_Delta_buf -= _Delta
}
return longArrayToString(_Data_buf)
}
func xor(a string, b string) string {
a = bin2hex(a)
b = bin2hex(b)
l := len(a)
var ret []string
//var re string
for i := 0; i < l; i += 4 {
a1, _ := strconv.ParseInt(a[i:i+4], 16, 32)
b1, _ := strconv.ParseInt(b[i:i+4], 16, 32)
t := a1 ^ b1
add := fmt.Sprintf("%x", t)
if len(add) < 4 {
for addzero := 4 - len(add); addzero > 0; addzero-- {
add = "0" + add
}
}
ret = append(ret, add)
}
var result []byte
for _, v := range ret {
t1, _ := strconv.ParseInt(v[0:2], 16, 32)
result = append(result, byte(t1))
t2, _ := strconv.ParseInt(v[2:4], 16, 32)
result = append(result, byte(t2))
continue
}
return string(result)
}
func bin2hex(_Data string) string {
var re []string
unicodeData := []byte(_Data)
for i := len(_Data) - 1; i >= 0; i-- {
unicodeFor16 := fmt.Sprintf("%x", unicodeData[i])
c := "00" + unicodeFor16
re = append(re, c[len(c)-2:])
}
return strings.Join(reverse(re), "")
}
func reverse(s []string) []string {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}
func longArrayToString(data []int64) string {
var by []byte
for i := 0; i < len(data); i++ {
i1 := int32(data[i]>>24) & 0xFF
by = append(by, byte(i1))
i2 := int32(data[i]>>16) & 0xFF
by = append(by, byte(i2))
i3 := int32(data[i]>>8) & 0xFF
by = append(by, byte(i3))
i4 := data[i] & 0xFF
by = append(by, byte(i4))
}
return string(by)
}
func stringToLongArray(str string) []int64 {
var re []int64
unicodeStr := []byte(str)
var unicode []int64
for _, v := range unicodeStr {
unicode = append(unicode, int64(v))
}
for i := 0; i < len(unicode); i += 4 {
var r int64
if i+4-len(unicode) > 0 {
switch len(unicode) - i {
case 1:
r = unicode[i+0] << 24
case 2:
r = unicode[i+0]<<24 | unicode[i+1]<<16
case 3:
r = unicode[i+0]<<24 | unicode[i+1]<<16 | unicode[i+2]<<8
}
} else {
r = (unicode[i+0]<<24 |
unicode[i+1]<<16 |
unicode[i+2]<<8 |
unicode[i+3]) >> 0
}
re = append(re, r)
}
return re
}
</code></pre>
<p>utils.go</p>
<pre><code>package se
import (
"reflect"
"unsafe"
)
// zero-copy
func Bytes2string(b []byte) string{
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{
Data: sliceHeader.Data,
Len: sliceHeader.Len,
}
return *(*string)(unsafe.Pointer(&sh))
}
</code></pre>
<h2>main</h2>
<pre><code>package main
import (
"fmt"
"jiemi/se"
)
const DecryptKey = "XHW_SHARE_ENCRYPT" // 加密的 key
func main() {
// 将 fiddler 的 hexview 复制到这里
fiddlerHexView := []byte { 0xC7, 0xA2, 0xE9, 0xA2, 0xCB, 0x73, 0x06, 0x3B, 0xE3, 0x41, 0xB5, 0xDB, 0xDF, 0x24, 0x80, 0x0E, 0x20, 0x11, 0xFE, 0x6E, 0x17, 0x93, 0xF9, 0xD5, 0xFB, 0x65, 0x31, 0xA9, 0x68, 0xE3, 0xDE, 0x3A, 0x8F, 0x86, 0xA9, 0x7D, 0x2C, 0x4A, 0xB8, 0x06, 0x03, 0x45, 0x95, 0x82, 0x36, 0x3A, 0x63, 0xD7, 0x60, 0x97, 0xB6, 0x6E, 0x75, 0xB1, 0x2C, 0x2F, 0xDA, 0x6A, 0x30, 0x66, 0x36, 0x3B, 0xA3, 0xEC, 0x0A, 0x9A, 0xB4, 0x11, 0xC7, 0xFA, 0x04, 0x53, 0xCA, 0xB2, 0x12, 0x7A, 0x64, 0xD1, 0x1A, 0x16, 0x8B, 0x00, 0xED, 0x35, 0xDA, 0x6E, 0xB2, 0x6A, 0xF9, 0xCA, 0x72, 0x9A, 0x97, 0xD6, 0x73, 0x5E, 0x5B, 0x9D, 0x58, 0x98, 0x9B, 0xC7, 0x09, 0x39, 0x67, 0x71, 0x35, 0xF1, 0xA0, 0xFC, 0x58, 0xBF, 0x0C, 0x4C, 0xE5, 0x84, 0x74, 0x5A, 0xD3, 0x7A, 0x39, 0x11, 0xF0, 0x57, 0x8A, 0x3E, 0xCA, 0x1C };
// 解密输出
bodyStr := se.Decrypt(se.Bytes2string(fiddlerHexView), DecryptKey)
fmt.Println(bodyStr)
}
</code></pre>
<p>postman</p>
<pre><code>package main
import (
"bytes"
"fmt"
"io/ioutil"
"jiemi/se"
"net/http"
)
const Key = "XHW_SHARE_ENCRYPT" // 加密的 key
const Url = "https://comrades.heywoodsminiprogram.com/api/user/article_index" // 请求的 url
// 请求参数 json
const Body = `
{
"user_id" : "crj5e85cdab89e0f84b375ec37a",
"look_user_id" : "crj5e85cdab89e0f84b375ec37a",
"num" :10
}
`
func main() {
bodyStr := se.Decrypt(se.Bytes2string(post(Url, requestBody())), Key)
fmt.Println(bodyStr)
}
func requestBody() []byte {
return []byte(se.Encrypt(Body, Key))
}
func post(url string, body []byte) []byte{
method := "POST"
payload := bytes.NewReader(body)
client := &http.Client {}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Referer", "https://servicewechat.com/wx8079336e30e71a13/152/page-frame.html")
req.Header.Set("Content-Type", "application/octet-stream")
res, err := client.Do(req)
defer res.Body.Close()
respBody, err := ioutil.ReadAll(res.Body)
return respBody
}
</code></pre>