mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-07 12:43:32 +08:00
feat: ecdh pubkey rotate
This commit is contained in:
parent
2826f14c1d
commit
857e891976
@ -20,6 +20,7 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/MiraiGo/protocol/crypto"
|
||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
@ -163,6 +164,7 @@ func NewClient(uin int64, password string) *QQClient {
|
||||
}
|
||||
|
||||
func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
||||
crypto.ECDH.FetchPubKey(uin)
|
||||
cli := &QQClient{
|
||||
Uin: uin,
|
||||
PasswordMd5: passwordMd5,
|
||||
|
@ -4,14 +4,18 @@ import (
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
type EncryptECDH struct {
|
||||
InitialShareKey []byte
|
||||
PublicKey []byte
|
||||
PublicKeyVer uint16
|
||||
}
|
||||
|
||||
type EncryptSession struct {
|
||||
@ -20,33 +24,28 @@ type EncryptSession struct {
|
||||
|
||||
var ECDH = &EncryptECDH{}
|
||||
|
||||
var tenKeyX = new(big.Int).SetBytes([]byte{
|
||||
0xEB, 0xCA, 0x94, 0xD7, 0x33, 0xE3, 0x99, 0xB2,
|
||||
0xDB, 0x96, 0xEA, 0xCD, 0xD3, 0xF6, 0x9A, 0x8B,
|
||||
0xB0, 0xF7, 0x42, 0x24, 0xE2, 0xB4, 0x4E, 0x33,
|
||||
0x57, 0x81, 0x22, 0x11, 0xD2, 0xE6, 0x2E, 0xFB,
|
||||
})
|
||||
|
||||
var tenKeyY = new(big.Int).SetBytes([]byte{
|
||||
0xC9, 0x1B, 0xB5, 0x53, 0x09, 0x8E, 0x25, 0xE3,
|
||||
0x3A, 0x79, 0x9A, 0xDC, 0x7F, 0x76, 0xFE, 0xB2,
|
||||
0x08, 0xDA, 0x7C, 0x65, 0x22, 0xCD, 0xB0, 0x71,
|
||||
0x9A, 0x30, 0x51, 0x80, 0xCC, 0x54, 0xA8, 0x2E,
|
||||
})
|
||||
const serverPublicKey = "04EBCA94D733E399B2DB96EACDD3F69A8BB0F74224E2B44E3357812211D2E62EFBC91BB553098E25E33A799ADC7F76FEB208DA7C6522CDB0719A305180CC54A82E"
|
||||
|
||||
func init() {
|
||||
ECDH.PublicKeyVer = 1
|
||||
ECDH.generateKey(serverPublicKey)
|
||||
}
|
||||
|
||||
func (e *EncryptECDH) generateKey(sPubKey string) {
|
||||
pub, err := hex.DecodeString(sPubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p256 := elliptic.P256()
|
||||
key, sx, sy, err := elliptic.GenerateKey(p256, rand.Reader)
|
||||
if err != nil {
|
||||
panic("Can't Create ECDH key pair")
|
||||
panic(err)
|
||||
}
|
||||
x, _ := p256.ScalarMult(tenKeyX, tenKeyY, key)
|
||||
tx, ty := elliptic.Unmarshal(p256, pub)
|
||||
x, _ := p256.ScalarMult(tx, ty, key)
|
||||
hash := md5.Sum(x.Bytes()[:16])
|
||||
ECDH.InitialShareKey = hash[:]
|
||||
ECDH.PublicKey = make([]byte, 65)[:0]
|
||||
ECDH.PublicKey = append(ECDH.PublicKey, 0x04)
|
||||
ECDH.PublicKey = append(ECDH.PublicKey, sx.Bytes()...)
|
||||
ECDH.PublicKey = append(ECDH.PublicKey, sy.Bytes()...)
|
||||
e.InitialShareKey = hash[:]
|
||||
e.PublicKey = elliptic.Marshal(p256, sx, sy)
|
||||
}
|
||||
|
||||
func (e *EncryptECDH) DoEncrypt(d, k []byte) []byte {
|
||||
@ -55,7 +54,7 @@ func (e *EncryptECDH) DoEncrypt(d, k []byte) []byte {
|
||||
w.WriteByte(0x01)
|
||||
w.Write(k)
|
||||
w.WriteUInt16(0x01_31)
|
||||
w.WriteUInt16(0x00_01)
|
||||
w.WriteUInt16(e.PublicKeyVer)
|
||||
w.WriteUInt16(uint16(len(ECDH.PublicKey)))
|
||||
w.Write(ECDH.PublicKey)
|
||||
w.EncryptAndWrite(ECDH.InitialShareKey, d)
|
||||
@ -82,3 +81,26 @@ func (e *EncryptSession) DoEncrypt(d, k []byte) []byte {
|
||||
func (e *EncryptSession) Id() byte {
|
||||
return 69
|
||||
}
|
||||
|
||||
type pubKeyResp struct {
|
||||
Meta struct {
|
||||
PubKeyVer uint16 `json:"KeyVer"`
|
||||
PubKey string `json:"PubKey"`
|
||||
} `json:"PubKeyMeta"`
|
||||
}
|
||||
|
||||
// FetchPubKey 从服务器获取PubKey
|
||||
func (e *EncryptECDH) FetchPubKey(uin int64) {
|
||||
resp, err := http.Get("https://keyrotate.qq.com/rotate_key?cipher_suite_ver=305&uin=" + strconv.FormatInt(uin, 10))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var pubKey = pubKeyResp{}
|
||||
err = jsoniter.NewDecoder(resp.Body).Decode(&pubKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
e.PublicKeyVer = pubKey.Meta.PubKeyVer
|
||||
e.generateKey(pubKey.Meta.PubKey) // todo check key sign
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user