github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/internal/auth/qimei.go (about) 1 package auth 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/md5" 8 crand "crypto/rand" 9 "crypto/rsa" 10 "crypto/x509" 11 "encoding/base64" 12 "encoding/hex" 13 "encoding/json" 14 "encoding/pem" 15 "fmt" 16 "math/rand" 17 "time" 18 19 "github.com/Mrs4s/MiraiGo/utils" 20 "github.com/tidwall/gjson" 21 ) 22 23 const ( 24 secret = "ZdJqM15EeO2zWc08" 25 rsaKey = `-----BEGIN PUBLIC KEY----- 26 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEIxgwoutfwoJxcGQeedgP7FG9 27 qaIuS0qzfR8gWkrkTZKM2iWHn2ajQpBRZjMSoSf6+KJGvar2ORhBfpDXyVtZCKpq 28 LQ+FLkpncClKVIrBwv6PHyUvuCb0rIarmgDnzkfQAqVufEtR64iazGDKatvJ9y6B 29 9NMbHddGSAUmRTCrHQIDAQAB 30 -----END PUBLIC KEY-----` 31 ) 32 33 func (info *Device) RequestQImei() { 34 if info.Protocol.Version().AppKey == "" { 35 return 36 } 37 38 // init params 39 payload, _ := json.Marshal(genRandomPayloadByDevice(info)) 40 cryptKey := utils.RandomStringRange(16, "abcdef1234567890") 41 ts := time.Now().Unix() * 1000 42 nonce := utils.RandomStringRange(16, "abcdef1234567890") 43 44 // init rsa key and aes key 45 publicKey := initPublicKey() 46 encryptedAesKey, _ := rsa.EncryptPKCS1v15(crand.Reader, publicKey, []byte(cryptKey)) 47 48 encryptedPayload := aesEncrypt(payload, []byte(cryptKey)) 49 50 key := base64.StdEncoding.EncodeToString(encryptedAesKey) 51 params := base64.StdEncoding.EncodeToString(encryptedPayload) 52 53 postData, _ := json.Marshal(map[string]any{ 54 "key": key, 55 "params": params, 56 "time": ts, 57 "nonce": nonce, 58 "sign": sign(key, params, fmt.Sprint(ts), nonce), 59 "extra": "", 60 }) 61 62 resp, _ := utils.HttpPostBytesWithCookie("https://snowflake.qq.com/ola/android", postData, "", "application/json") 63 if gjson.GetBytes(resp, "code").Int() != 0 { 64 return 65 } 66 encryptedResponse, _ := base64.StdEncoding.DecodeString(gjson.GetBytes(resp, "data").String()) 67 if len(encryptedResponse) == 0 { 68 return 69 } 70 decryptedResponse := aesDecrypt(encryptedResponse, []byte(cryptKey)) 71 info.QImei16 = gjson.GetBytes(decryptedResponse, "q16").String() 72 info.QImei36 = gjson.GetBytes(decryptedResponse, "q36").String() 73 } 74 75 func initPublicKey() *rsa.PublicKey { 76 blockPub, _ := pem.Decode([]byte(rsaKey)) 77 pub, _ := x509.ParsePKIXPublicKey(blockPub.Bytes) 78 return pub.(*rsa.PublicKey) 79 } 80 81 func sign(key, params, ts, nonce string) string { 82 h := md5.Sum([]byte(key + params + ts + nonce + secret)) 83 return hex.EncodeToString(h[:]) 84 } 85 86 func aesEncrypt(src []byte, key []byte) []byte { 87 block, _ := aes.NewCipher(key) 88 ecb := cipher.NewCBCEncrypter(block, key) 89 content := src 90 content = pkcs5Padding(content, block.BlockSize()) 91 crypted := make([]byte, len(content)) 92 ecb.CryptBlocks(crypted, content) 93 return crypted 94 } 95 96 func aesDecrypt(crypt []byte, key []byte) []byte { 97 block, _ := aes.NewCipher(key) 98 ecb := cipher.NewCBCDecrypter(block, key) 99 decrypted := make([]byte, len(crypt)) 100 ecb.CryptBlocks(decrypted, crypt) 101 return pkcs5Trimming(decrypted) 102 } 103 104 func pkcs5Padding(ciphertext []byte, blockSize int) []byte { 105 padding := blockSize - len(ciphertext)%blockSize 106 padtext := bytes.Repeat([]byte{byte(padding)}, padding) 107 return append(ciphertext, padtext...) 108 } 109 110 func pkcs5Trimming(encrypt []byte) []byte { 111 padding := encrypt[len(encrypt)-1] 112 return encrypt[:len(encrypt)-int(padding)] 113 } 114 115 func genRandomPayloadByDevice(info *Device) map[string]any { 116 now := time.Now() 117 seed := int64(0x6F4) 118 for _, b := range info.Guid { 119 seed += int64(b) 120 } 121 fixedRand := rand.New(rand.NewSource(seed)) 122 123 reserved := map[string]string{ 124 "harmony": "0", 125 "clone": "0", 126 "containe": "", 127 "oz": "UhYmelwouA+V2nPWbOvLTgN2/m8jwGB+yUB5v9tysQg=", 128 "oo": "Xecjt+9S1+f8Pz2VLSxgpw==", 129 "kelong": "0", 130 "uptimes": time.Unix(now.Unix()-fixedRand.Int63n(14400), 0).Format(time.DateTime), 131 "multiUser": "0", 132 "bod": string(info.Board), 133 "brd": string(info.Brand), 134 "dv": string(info.Device), 135 "firstLevel": "", 136 "manufact": string(info.Brand), 137 "name": string(info.Model), 138 "host": "se.infra", 139 "kernel": string(info.ProcVersion), 140 } 141 reservedBytes, _ := json.Marshal(reserved) 142 deviceType := "Phone" 143 if info.Protocol == AndroidPad { 144 deviceType = "Pad" 145 } 146 beaconId := "" 147 timeMonth := time.Now().Format("2006-01-") + "01" 148 rand1 := fixedRand.Intn(899999) + 100000 149 rand2 := fixedRand.Intn(899999999) + 100000000 150 for i := 1; i <= 40; i++ { 151 switch i { 152 case 1, 2, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30, 33, 34, 37, 38: 153 beaconId += fmt.Sprintf("k%v:%v%v.%v", i, timeMonth, rand1, rand2) 154 case 3: 155 beaconId += "k3:0000000000000000" 156 case 4: 157 beaconId += "k4:" + utils.RandomStringRange(16, "123456789abcdef") 158 default: 159 beaconId += fmt.Sprintf("k%v:%v", i, fixedRand.Intn(10000)) 160 } 161 beaconId += ";" 162 } 163 return map[string]any{ 164 "androidId": string(info.AndroidId), 165 "platformId": 1, 166 "appKey": info.Protocol.Version().AppKey, 167 "appVersion": info.Protocol.Version().SortVersionName, 168 "beaconIdSrc": beaconId, 169 "brand": string(info.Brand), 170 "channelId": "2017", 171 "cid": "", 172 "imei": info.IMEI, 173 "imsi": "", 174 "mac": "", 175 "model": string(info.Model), 176 "networkType": "unknown", 177 "oaid": "", 178 "osVersion": "Android " + string(info.Version.Release) + ",level " + fmt.Sprint(info.Version.SDK), 179 "qimei": "", 180 "qimei36": "", 181 "sdkVersion": "1.2.13.6", 182 "audit": "", 183 "userId": "{}", 184 "packageId": info.Protocol.Version().ApkId, 185 "deviceType": deviceType, 186 "sdkName": "", 187 "reserved": string(reservedBytes), 188 } 189 }