diff --git a/client/builders.go b/client/builders.go index 8d6f700d..af119382 100644 --- a/client/builders.go +++ b/client/builders.go @@ -31,7 +31,7 @@ var ( func (c *QQClient) buildLoginPacket() (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(9) if c.AllowSlider { w.WriteUInt16(0x17) @@ -99,7 +99,7 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) { func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(20) w.WriteUInt16(4) @@ -116,7 +116,7 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) { func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) { watch := genVersionInfo(AndroidWatch) seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(0, 0x812, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(0, 0x812, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteHex(`0001110000001000000072000000`) // trans header w.WriteUInt32(uint32(time.Now().Unix())) w.Write(packets.BuildCode2DRequestPacket(0, 0, 0x31, func(w *binary.Writer) { @@ -143,7 +143,7 @@ func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) { func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) { watch := genVersionInfo(AndroidWatch) seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(0, 0x812, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(0, 0x812, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteHex(`0000620000001000000072000000`) // trans header w.WriteUInt32(uint32(time.Now().Unix())) w.Write(packets.BuildCode2DRequestPacket(1, 0, 0x12, func(w *binary.Writer) { @@ -165,7 +165,7 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(9) w.WriteUInt16(24) @@ -233,7 +233,7 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(2) // sub command w.WriteUInt16(4) @@ -249,7 +249,7 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(8) w.WriteUInt16(6) @@ -267,7 +267,7 @@ func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) { func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(7) w.WriteUInt16(7) @@ -286,7 +286,7 @@ func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) { func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(2) w.WriteUInt16(4) @@ -356,7 +356,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) { func (c *QQClient) buildRequestChangeSigPacket() (uint16, []byte) { seq := c.nextSeq() - req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) { + req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, c.ecdh, c.RandomKey, func(w *binary.Writer) { w.WriteUInt16(11) w.WriteUInt16(17) diff --git a/client/client.go b/client/client.go index 73a790f5..ef53dcf4 100644 --- a/client/client.go +++ b/client/client.go @@ -60,6 +60,7 @@ type QQClient struct { version *versionInfo deviceInfo *DeviceInfo alive bool + ecdh *crypto.EncryptECDH // tlv cache t104 []byte @@ -189,7 +190,6 @@ func NewClientEmpty() *QQClient { } func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { - crypto.ECDH.FetchPubKey(uin) cli := &QQClient{ Uin: uin, PasswordMd5: passwordMd5, @@ -209,7 +209,9 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { onlinePushCache: utils.NewCache(time.Second * 15), servers: []*net.TCPAddr{}, alive: true, + ecdh: crypto.NewEcdh(), } + cli.ecdh.FetchPubKey(uin) cli.UseDevice(SystemDeviceInfo) sso, err := getSSOAddress() if err == nil && len(sso) > 0 { diff --git a/client/network.go b/client/network.go index 1bac586d..4020c8fd 100644 --- a/client/network.go +++ b/client/network.go @@ -289,7 +289,7 @@ func (c *QQClient) netLoop() { continue } if pkt.Flag2 == 2 { - pkt.Payload, err = pkt.DecryptPayload(c.RandomKey, c.sigInfo.wtSessionTicketKey) + pkt.Payload, err = pkt.DecryptPayload(c.ecdh.InitialShareKey, c.RandomKey, c.sigInfo.wtSessionTicketKey) if err != nil { c.Error("decrypt payload error: %v", err) continue diff --git a/protocol/crypto/crypto.go b/protocol/crypto/crypto.go index 54e3e0d0..34e65bea 100644 --- a/protocol/crypto/crypto.go +++ b/protocol/crypto/crypto.go @@ -22,13 +22,14 @@ type EncryptSession struct { T133 []byte } -var ECDH = &EncryptECDH{} - const serverPublicKey = "04EBCA94D733E399B2DB96EACDD3F69A8BB0F74224E2B44E3357812211D2E62EFBC91BB553098E25E33A799ADC7F76FEB208DA7C6522CDB0719A305180CC54A82E" -func init() { - ECDH.PublicKeyVer = 1 - ECDH.generateKey(serverPublicKey) +func NewEcdh() *EncryptECDH { + e := &EncryptECDH{ + PublicKeyVer: 1, + } + e.generateKey(serverPublicKey) + return e } func (e *EncryptECDH) generateKey(sPubKey string) { @@ -55,9 +56,9 @@ func (e *EncryptECDH) DoEncrypt(d, k []byte) []byte { w.Write(k) w.WriteUInt16(0x01_31) w.WriteUInt16(e.PublicKeyVer) - w.WriteUInt16(uint16(len(ECDH.PublicKey))) - w.Write(ECDH.PublicKey) - w.EncryptAndWrite(ECDH.InitialShareKey, d) + w.WriteUInt16(uint16(len(e.PublicKey))) + w.Write(e.PublicKey) + w.EncryptAndWrite(e.InitialShareKey, d) return w.Bytes() } diff --git a/protocol/packets/global.go b/protocol/packets/global.go index 9ba25a4b..b5c8d567 100644 --- a/protocol/packets/global.go +++ b/protocol/packets/global.go @@ -6,7 +6,6 @@ import ( "github.com/pkg/errors" "github.com/Mrs4s/MiraiGo/binary" - "github.com/Mrs4s/MiraiGo/protocol/crypto" ) var ( @@ -190,7 +189,7 @@ func parseSsoFrame(payload []byte, flag2 byte) (*IncomingPacket, error) { }, nil } -func (pkt *IncomingPacket) DecryptPayload(random, sessionKey []byte) ([]byte, error) { +func (pkt *IncomingPacket) DecryptPayload(ecdhShareKey, random, sessionKey []byte) ([]byte, error) { reader := binary.NewReader(pkt.Payload) if reader.ReadByte() != 2 { return nil, ErrUnknownFlag @@ -211,7 +210,7 @@ func (pkt *IncomingPacket) DecryptPayload(random, sessionKey []byte) ([]byte, er decrypted = tea.Decrypt(d) } }() - tea := binary.NewTeaCipher(crypto.ECDH.InitialShareKey) + tea := binary.NewTeaCipher(ecdhShareKey) decrypted = tea.Decrypt(d) return }()