diff --git a/cmd/dispatch/key/dispatchKey.bin b/cmd/dispatch/key/dispatchKey.bin deleted file mode 100644 index 29b396f1..00000000 Binary files a/cmd/dispatch/key/dispatchKey.bin and /dev/null differ diff --git a/cmd/dispatch/key/dispatchSeed.bin b/cmd/dispatch/key/dispatchSeed.bin deleted file mode 100644 index 0100e2c8..00000000 Binary files a/cmd/dispatch/key/dispatchSeed.bin and /dev/null differ diff --git a/cmd/dispatch/key/secretKey.bin b/cmd/dispatch/key/secretKey.bin deleted file mode 100644 index 0ff2db51..00000000 Binary files a/cmd/dispatch/key/secretKey.bin and /dev/null differ diff --git a/cmd/dispatch/key/secretKeyBuffer.bin b/cmd/dispatch/key/secretKeyBuffer.bin deleted file mode 100644 index d767aa91..00000000 --- a/cmd/dispatch/key/secretKeyBuffer.bin +++ /dev/null @@ -1 +0,0 @@ -lt1L ܟ.\pXP"ƀ(a \ No newline at end of file diff --git a/cmd/gate/key/dispatchKey.bin b/cmd/gate/key/dispatchKey.bin deleted file mode 100644 index 29b396f1..00000000 Binary files a/cmd/gate/key/dispatchKey.bin and /dev/null differ diff --git a/cmd/gate/key/dispatchSeed.bin b/cmd/gate/key/dispatchSeed.bin deleted file mode 100644 index 0100e2c8..00000000 Binary files a/cmd/gate/key/dispatchSeed.bin and /dev/null differ diff --git a/cmd/gate/key/secretKey.bin b/cmd/gate/key/secretKey.bin deleted file mode 100644 index 0ff2db51..00000000 Binary files a/cmd/gate/key/secretKey.bin and /dev/null differ diff --git a/cmd/gate/key/secretKeyBuffer.bin b/cmd/gate/key/secretKeyBuffer.bin deleted file mode 100644 index d767aa91..00000000 --- a/cmd/gate/key/secretKeyBuffer.bin +++ /dev/null @@ -1 +0,0 @@ -lt1L ܟ.\pXP"ƀ(a \ No newline at end of file diff --git a/common/region/region.go b/common/region/region.go index 007ff881..c0f6d0bd 100644 --- a/common/region/region.go +++ b/common/region/region.go @@ -1,6 +1,7 @@ package region import ( + "hk4e/pkg/random" "os" "hk4e/pkg/endec" @@ -32,23 +33,16 @@ func LoadRsaKey() (signRsaKey []byte, encRsaKeyMap map[string][]byte, pwdRsaKey return signRsaKey, encRsaKeyMap, pwdRsaKey } -func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp) { - dispatchKey, err := os.ReadFile("key/dispatchKey.bin") - if err != nil { - logger.LOG.Error("open dispatchKey.bin error: %v", err) - return nil, nil - } - dispatchSeed, err := os.ReadFile("key/dispatchSeed.bin") - if err != nil { - logger.LOG.Error("open dispatchSeed.bin error: %v", err) - return nil, nil - } +func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) { + dispatchEc2b := random.NewEc2b() + dispatchEc2bData := dispatchEc2b.Bytes() + dispatchXorKey := dispatchEc2b.XorKey() // RegionCurr regionCurr := new(proto.QueryCurrRegionHttpRsp) regionCurr.RegionInfo = &proto.RegionInfo{ GateserverIp: kcpAddr, GateserverPort: uint32(kcpPort), - SecretKey: dispatchSeed, + SecretKey: dispatchEc2bData, } // RegionList customConfigStr := ` @@ -62,7 +56,7 @@ func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *pr } ` customConfig := []byte(customConfigStr) - endec.Xor(customConfig, dispatchKey) + endec.Xor(customConfig, dispatchXorKey) serverList := make([]*proto.RegionSimpleInfo, 0) server := &proto.RegionSimpleInfo{ Name: "os_usa", @@ -73,8 +67,8 @@ func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *pr serverList = append(serverList, server) regionList := new(proto.QueryRegionListHttpRsp) regionList.RegionList = serverList - regionList.ClientSecretKey = dispatchSeed + regionList.ClientSecretKey = dispatchEc2bData regionList.ClientCustomConfigEncrypted = customConfig regionList.EnableLoginPc = true - return regionCurr, regionList + return regionCurr, regionList, dispatchEc2b } diff --git a/dispatch/app/app.go b/dispatch/app/app.go index 5467cbf8..de6b4ad0 100644 --- a/dispatch/app/app.go +++ b/dispatch/app/app.go @@ -2,7 +2,6 @@ package app import ( "context" - "github.com/nats-io/nats.go" _ "net/http/pprof" "os" "os/signal" @@ -26,20 +25,6 @@ func Run(ctx context.Context, configFile string) error { _ = controller.NewController(db) - // TODO 临时写一下用来传递新的密钥后面改RPC - conn, err := nats.Connect(config.CONF.MQ.NatsUrl) - if err != nil { - logger.LOG.Error("connect nats error: %v", err) - return nil - } - natsMsg := nats.NewMsg("GATE_KEY_HK4E") - natsMsg.Data = []byte{0x00, 0xff} - err = conn.PublishMsg(natsMsg) - if err != nil { - logger.LOG.Error("nats publish msg error: %v", err) - return nil - } - c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) for { diff --git a/dispatch/controller/controller.go b/dispatch/controller/controller.go index 6bb740c7..25f61815 100644 --- a/dispatch/controller/controller.go +++ b/dispatch/controller/controller.go @@ -2,6 +2,8 @@ package controller import ( "encoding/base64" + "encoding/binary" + "github.com/nats-io/nats.go" "net/http" "strconv" @@ -28,7 +30,26 @@ func NewController(dao *dao.Dao) (r *Controller) { r.dao = dao r.regionListBase64 = "" r.regionCurrBase64 = "" - regionCurr, regionList := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort) + regionCurr, regionList, dispatchEc2b := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort) + + // TODO 临时写一下用来传递新的密钥后面改RPC + conn, err := nats.Connect(config.CONF.MQ.NatsUrl) + if err != nil { + logger.LOG.Error("connect nats error: %v", err) + return nil + } + natsMsg := nats.NewMsg("GATE_KEY_HK4E") + natsMsg.Data = make([]byte, 8) + dispatchEc2bSeed := dispatchEc2b.Seed() + binary.BigEndian.PutUint64(natsMsg.Data, dispatchEc2bSeed) + err = conn.PublishMsg(natsMsg) + if err != nil { + logger.LOG.Error("nats publish msg error: %v", err) + return nil + } + conn.Close() + logger.LOG.Debug("send new dispatch ec2b seed: %v", dispatchEc2bSeed) + r.signRsaKey, r.encRsaKeyMap, r.pwdRsaKey = region.LoadRsaKey() regionCurrModify, err := pb.Marshal(regionCurr) if err != nil { diff --git a/gate/app/app.go b/gate/app/app.go index 24e132d4..27719df5 100644 --- a/gate/app/app.go +++ b/gate/app/app.go @@ -35,7 +35,7 @@ func Run(ctx context.Context, configFile string) error { forwardManager := forward.NewForwardManager(protoMsgInput, protoMsgOutput, kcpEventInput, kcpEventOutput, netMsgInput, netMsgOutput) forwardManager.Start() - messageQueue := mq.NewMessageQueue(netMsgInput, netMsgOutput) + messageQueue := mq.NewMessageQueue(netMsgInput, netMsgOutput, kcpEventInput) messageQueue.Start() defer messageQueue.Close() diff --git a/gate/forward/forward.go b/gate/forward/forward.go index 4b0b87c1..22c5c13b 100644 --- a/gate/forward/forward.go +++ b/gate/forward/forward.go @@ -1,7 +1,7 @@ package forward import ( - "os" + "hk4e/pkg/random" "runtime" "sync" "time" @@ -48,12 +48,14 @@ type ForwardManager struct { // kcpConv -> headMeta convHeadMetaMap map[uint64]*ClientHeadMeta convHeadMetaMapLock sync.RWMutex - secretKeyBuffer []byte - kcpEventInput chan *net.KcpEvent - kcpEventOutput chan *net.KcpEvent - regionCurr *proto.QueryCurrRegionHttpRsp - signRsaKey []byte - encRsaKeyMap map[string][]byte + // kcpConv -> seed + convSeedMap map[uint64]uint64 + convSeedMapLock sync.RWMutex + kcpEventInput chan *net.KcpEvent + kcpEventOutput chan *net.KcpEvent + regionCurr *proto.QueryCurrRegionHttpRsp + signRsaKey []byte + encRsaKeyMap map[string][]byte } func NewForwardManager( @@ -70,6 +72,7 @@ func NewForwardManager( r.userIdConvMap = make(map[uint32]uint64) r.convAddrMap = make(map[uint64]string) r.convHeadMetaMap = make(map[uint64]*ClientHeadMeta) + r.convSeedMap = make(map[uint64]uint64) r.kcpEventInput = kcpEventInput r.kcpEventOutput = kcpEventOutput return r @@ -97,23 +100,21 @@ func (f *ForwardManager) kcpEventHandle() { EventId: net.KcpPacketSendListen, EventMessage: "Disable", } - // 登录成功 通知GS初始化相关数据 - userId, exist := f.getUserIdByConvId(event.ConvId) + seed, exist := f.getSeedByConvId(event.ConvId) if !exist { - logger.LOG.Error("can not find userId by convId") + logger.LOG.Error("can not find seed by convId") continue } - headMeta, exist := f.getHeadMetaByConvId(event.ConvId) - if !exist { - logger.LOG.Error("can not find client head metadata by convId") - continue + keyBlock := random.NewKeyBlock(seed) + xorKey := keyBlock.XorKey() + key := make([]byte, 4096) + copy(key, xorKey[:]) + // 改变密钥 + f.kcpEventInput <- &net.KcpEvent{ + ConvId: event.ConvId, + EventId: net.KcpXorKeyChange, + EventMessage: key, } - netMsg := new(cmd.NetMsg) - netMsg.UserId = userId - netMsg.EventId = cmd.UserLoginNotify - netMsg.ClientSeq = headMeta.seq - f.netMsgInput <- netMsg - logger.LOG.Info("send to gs user login ok, ConvId: %v, UserId: %v", event.ConvId, netMsg.UserId) case net.KcpConnCloseNotify: // 连接断开通知 userId, exist := f.getUserIdByConvId(event.ConvId) @@ -139,6 +140,7 @@ func (f *ForwardManager) kcpEventHandle() { } f.deleteAddrByConvId(event.ConvId) f.deleteHeadMetaByConvId(event.ConvId) + f.deleteSeedByConvId(event.ConvId) case net.KcpConnEstNotify: // 连接建立通知 addr, ok := event.EventMessage.(string) @@ -183,15 +185,9 @@ func (f *ForwardManager) kcpEventHandle() { func (f *ForwardManager) Start() { // 读取密钥相关文件 - var err error = nil - f.secretKeyBuffer, err = os.ReadFile("key/secretKeyBuffer.bin") - if err != nil { - logger.LOG.Error("open secretKeyBuffer.bin error") - return - } f.signRsaKey, f.encRsaKeyMap, _ = region.LoadRsaKey() // region - regionCurr, _ := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort) + regionCurr, _, _ := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort) f.regionCurr = regionCurr // kcp事件监听 go f.kcpEventHandle() @@ -226,12 +222,6 @@ func (f *ForwardManager) sendNetMsgToGameServer() { if getPlayerTokenRsp == nil { continue } - // 改变解密密钥 - f.kcpEventInput <- &net.KcpEvent{ - ConvId: protoMsg.ConvId, - EventId: net.KcpXorKeyChange, - EventMessage: "DEC", - } // 返回数据到客户端 resp := new(net.ProtoMsg) resp.ConvId = protoMsg.ConvId @@ -249,29 +239,30 @@ func (f *ForwardManager) sendNetMsgToGameServer() { if playerLoginRsp == nil { continue } - // 改变加密密钥 - f.kcpEventInput <- &net.KcpEvent{ - ConvId: protoMsg.ConvId, - EventId: net.KcpXorKeyChange, - EventMessage: "ENC", + // 返回数据到客户端 + resp := new(net.ProtoMsg) + resp.ConvId = protoMsg.ConvId + resp.CmdId = cmd.PlayerLoginRsp + resp.HeadMessage = f.getHeadMsg(protoMsg.HeadMessage.ClientSequenceId) + resp.PayloadMessage = playerLoginRsp + f.protoMsgInput <- resp + // 登录成功 通知GS初始化相关数据 + userId, exist := f.getUserIdByConvId(protoMsg.ConvId) + if !exist { + logger.LOG.Error("can not find userId by convId") + continue } - // 开启发包监听 - f.kcpEventInput <- &net.KcpEvent{ - ConvId: protoMsg.ConvId, - EventId: net.KcpPacketSendListen, - EventMessage: "Enable", + headMeta, exist := f.getHeadMetaByConvId(protoMsg.ConvId) + if !exist { + logger.LOG.Error("can not find client head metadata by convId") + continue } - go func() { - // 保证kcp事件已成功生效 - time.Sleep(time.Millisecond * 50) - // 返回数据到客户端 - resp := new(net.ProtoMsg) - resp.ConvId = protoMsg.ConvId - resp.CmdId = cmd.PlayerLoginRsp - resp.HeadMessage = f.getHeadMsg(protoMsg.HeadMessage.ClientSequenceId) - resp.PayloadMessage = playerLoginRsp - f.protoMsgInput <- resp - }() + netMsg := new(cmd.NetMsg) + netMsg.UserId = userId + netMsg.EventId = cmd.UserLoginNotify + netMsg.ClientSeq = headMeta.seq + f.netMsgInput <- netMsg + logger.LOG.Info("send to gs user login ok, ConvId: %v, UserId: %v", protoMsg.ConvId, netMsg.UserId) case cmd.SetPlayerBornDataReq: // 玩家注册请求 if connState != ConnAlive { @@ -480,6 +471,25 @@ func (f *ForwardManager) deleteHeadMetaByConvId(convId uint64) { f.convHeadMetaMapLock.Unlock() } +func (f *ForwardManager) getSeedByConvId(convId uint64) (seed uint64, exist bool) { + f.convSeedMapLock.RLock() + seed, exist = f.convSeedMap[convId] + f.convSeedMapLock.RUnlock() + return seed, exist +} + +func (f *ForwardManager) setSeedByConvId(convId uint64, seed uint64) { + f.convSeedMapLock.Lock() + f.convSeedMap[convId] = seed + f.convSeedMapLock.Unlock() +} + +func (f *ForwardManager) deleteSeedByConvId(convId uint64) { + f.convSeedMapLock.Lock() + delete(f.convSeedMap, convId) + f.convSeedMapLock.Unlock() +} + // 改变网关开放状态 func (f *ForwardManager) ChangeGateOpenState(isOpen bool) bool { f.kcpEventInput <- &net.KcpEvent{ diff --git a/gate/forward/login_hk4e.go b/gate/forward/login_hk4e.go index f077a3ec..42f84a8d 100644 --- a/gate/forward/login_hk4e.go +++ b/gate/forward/login_hk4e.go @@ -4,8 +4,11 @@ import ( "bytes" "encoding/base64" "encoding/binary" + "fmt" "hk4e/dispatch/controller" "hk4e/pkg/httpclient" + "hk4e/pkg/random" + "math/rand" "strconv" "strings" @@ -69,15 +72,16 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken rsp.Uid = tokenVerifyRsp.PlayerID // TODO 不同的token rsp.Token = "xxx" - rsp.AccountType = 1 + data := make([]byte, 16+32) + rand.Read(data) + rsp.SecurityCmdBuffer = data[16:] + rsp.ClientVersionRandomKey = fmt.Sprintf("%03x-%012x", data[:3], data[4:16]) // TODO 要确定一下新注册的号这个值该返回什么 + rsp.AccountType = 1 rsp.IsProficientPlayer = true - rsp.SecretKeySeed = 11468049314633205968 - rsp.SecurityCmdBuffer = f.secretKeyBuffer rsp.PlatformType = 3 rsp.ChannelId = 1 rsp.CountryCode = "US" - rsp.ClientVersionRandomKey = "c25-314dd05b0b5f" rsp.RegPlatform = 3 addr, exist := f.getAddrByConvId(convId) if !exist { @@ -87,7 +91,6 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken split := strings.Split(addr, ":") rsp.ClientIpStr = split[0] if req.GetKeyId() != 0 { - // pre check logger.LOG.Debug("do hk4e 2.8 rsa logic") keyId := strconv.Itoa(int(req.GetKeyId())) encPubPrivKey, exist := f.encRsaKeyMap[keyId] @@ -111,13 +114,6 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken logger.LOG.Error("parse client seed base64 error: %v", err) return nil } - // create error rsp info - clientSeedEncCopy := make([]byte, len(clientSeedEnc)) - copy(clientSeedEncCopy, clientSeedEnc) - endec.Xor(clientSeedEncCopy, []byte{0x9f, 0x26, 0xb2, 0x17, 0x61, 0x5f, 0xc8, 0x00}) - rsp.ServerRandKey = base64.StdEncoding.EncodeToString(clientSeedEncCopy) - rsp.Sign = "bm90aGluZyBoZXJl" - // do clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey) if err != nil { logger.LOG.Error("rsa dec error: %v", err) @@ -129,7 +125,10 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken logger.LOG.Error("parse client seed to uint64 error: %v", err) return rsp } - seedUint64 := uint64(11468049314633205968) ^ clientSeedUint64 + timeRand := random.GetTimeRand() + serverSeedUint64 := timeRand.Uint64() + f.setSeedByConvId(convId, serverSeedUint64) + seedUint64 := serverSeedUint64 ^ clientSeedUint64 seedBuf := new(bytes.Buffer) err = binary.Write(seedBuf, binary.BigEndian, seedUint64) if err != nil { @@ -149,6 +148,12 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken } rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc) rsp.Sign = base64.StdEncoding.EncodeToString(seedSign) + // 开启发包监听 + f.kcpEventInput <- &net.KcpEvent{ + ConvId: convId, + EventId: net.KcpPacketSendListen, + EventMessage: "Enable", + } } return rsp } @@ -170,6 +175,7 @@ func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) ( rsp.IsUseAbilityHash = true rsp.AbilityHashCode = 1844674 rsp.GameBiz = "hk4e_global" + rsp.ClientDataVersion = f.regionCurr.RegionInfo.ClientDataVersion rsp.ClientSilenceDataVersion = f.regionCurr.RegionInfo.ClientSilenceDataVersion rsp.ClientMd5 = f.regionCurr.RegionInfo.ClientDataMd5 @@ -177,6 +183,7 @@ func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) ( rsp.ResVersionConfig = f.regionCurr.RegionInfo.ResVersionConfig rsp.ClientVersionSuffix = f.regionCurr.RegionInfo.ClientVersionSuffix rsp.ClientSilenceVersionSuffix = f.regionCurr.RegionInfo.ClientSilenceVersionSuffix + rsp.IsScOpen = false rsp.RegisterCps = "mihoyo" rsp.CountryCode = "US" diff --git a/gate/mq/mq.go b/gate/mq/mq.go index 3aa8926f..e5283599 100644 --- a/gate/mq/mq.go +++ b/gate/mq/mq.go @@ -1,8 +1,11 @@ package mq import ( + "encoding/binary" "hk4e/common/config" + "hk4e/gate/net" "hk4e/pkg/logger" + "hk4e/pkg/random" "hk4e/protocol/cmd" "github.com/nats-io/nats.go" @@ -18,7 +21,7 @@ type MessageQueue struct { cmdProtoMap *cmd.CmdProtoMap } -func NewMessageQueue(netMsgInput chan *cmd.NetMsg, netMsgOutput chan *cmd.NetMsg) (r *MessageQueue) { +func NewMessageQueue(netMsgInput chan *cmd.NetMsg, netMsgOutput chan *cmd.NetMsg, kcpEventInput chan *net.KcpEvent) (r *MessageQueue) { r = new(MessageQueue) conn, err := nats.Connect(config.CONF.MQ.NatsUrl) if err != nil { @@ -43,7 +46,16 @@ func NewMessageQueue(netMsgInput chan *cmd.NetMsg, netMsgOutput chan *cmd.NetMsg go func() { for { natsMsg := <-keyNatsMsgChan - logger.LOG.Error("GATE_KEY_HK4E %v", natsMsg.Data) + dispatchEc2bSeed := binary.BigEndian.Uint64(natsMsg.Data) + logger.LOG.Debug("recv new dispatch ec2b seed: %v", dispatchEc2bSeed) + gateDispatchEc2b := random.NewEc2b() + gateDispatchEc2b.SetSeed(dispatchEc2bSeed) + gateDispatchXorKey := gateDispatchEc2b.XorKey() + // 改变密钥 + kcpEventInput <- &net.KcpEvent{ + EventId: net.KcpDispatchKeyChange, + EventMessage: gateDispatchXorKey, + } } }() diff --git a/gate/net/kcp_connect_manager.go b/gate/net/kcp_connect_manager.go index aa7518c1..2b6303af 100644 --- a/gate/net/kcp_connect_manager.go +++ b/gate/net/kcp_connect_manager.go @@ -3,7 +3,6 @@ package net import ( "bytes" "encoding/binary" - "os" "strconv" "sync" "time" @@ -14,11 +13,6 @@ import ( "hk4e/pkg/random" ) -type KcpXorKey struct { - encKey []byte - decKey []byte -} - type KcpConnectManager struct { openState bool connMap map[uint64]*kcp.UDPSession @@ -36,10 +30,10 @@ type KcpConnectManager struct { kcpSendListenMap map[uint64]bool kcpSendListenMapLock sync.RWMutex // key - dispatchKey []byte - secretKey []byte - kcpKeyMap map[uint64]*KcpXorKey - kcpKeyMapLock sync.RWMutex + dispatchKey []byte + dispatchKeyLock sync.RWMutex + kcpKeyMap map[uint64][]byte + kcpKeyMapLock sync.RWMutex // conv短时间内唯一生成 convGenMap map[uint64]int64 convGenMapLock sync.RWMutex @@ -57,7 +51,7 @@ func NewKcpConnectManager(protoMsgInput chan *ProtoMsg, protoMsgOutput chan *Pro r.kcpRawSendChanMap = make(map[uint64]chan *ProtoMsg) r.kcpRecvListenMap = make(map[uint64]bool) r.kcpSendListenMap = make(map[uint64]bool) - r.kcpKeyMap = make(map[uint64]*KcpXorKey) + r.kcpKeyMap = make(map[uint64][]byte) r.convGenMap = make(map[uint64]int64) return r } @@ -65,17 +59,7 @@ func NewKcpConnectManager(protoMsgInput chan *ProtoMsg, protoMsgOutput chan *Pro func (k *KcpConnectManager) Start() { go func() { // key - var err error = nil - k.dispatchKey, err = os.ReadFile("key/dispatchKey.bin") - if err != nil { - logger.LOG.Error("open dispatchKey.bin error") - return - } - k.secretKey, err = os.ReadFile("key/secretKey.bin") - if err != nil { - logger.LOG.Error("open secretKey.bin error") - return - } + k.dispatchKey = make([]byte, 4096) // kcp port := strconv.FormatInt(int64(config.CONF.Hk4e.KcpPort), 10) listener, err := kcp.ListenWithOptions("0.0.0.0:"+port, nil, 0, 0) @@ -110,10 +94,9 @@ func (k *KcpConnectManager) Start() { k.connMap[convId] = conn k.connMapLock.Unlock() k.kcpKeyMapLock.Lock() - k.kcpKeyMap[convId] = &KcpXorKey{ - encKey: k.dispatchKey, - decKey: k.dispatchKey, - } + k.dispatchKeyLock.RLock() + k.kcpKeyMap[convId] = k.dispatchKey + k.dispatchKeyLock.RUnlock() k.kcpKeyMapLock.Unlock() go k.recvHandle(convId) kcpRawSendChan := make(chan *ProtoMsg, 10000) diff --git a/gate/net/kcp_endecode.go b/gate/net/kcp_endecode.go index bd6d05cd..00630f17 100644 --- a/gate/net/kcp_endecode.go +++ b/gate/net/kcp_endecode.go @@ -42,7 +42,7 @@ func (k *KcpConnectManager) decodeBinToPayload(data []byte, convId uint64, kcpMs logger.LOG.Error("kcp xor key not exist, convId: %v", convId) return } - endec.Xor(data, xorKey.decKey) + endec.Xor(data, xorKey) k.decodeRecur(data, convId, kcpMsgList) } @@ -183,6 +183,6 @@ func (k *KcpConnectManager) encodePayloadToBin(kcpMsg *KcpMsg) (bin []byte) { logger.LOG.Error("kcp xor key not exist, convId: %v", kcpMsg.ConvId) return } - endec.Xor(bin, xorKey.encKey) + endec.Xor(bin, xorKey) return bin } diff --git a/gate/net/kcp_event.go b/gate/net/kcp_event.go index f607e771..ced323e1 100644 --- a/gate/net/kcp_event.go +++ b/gate/net/kcp_event.go @@ -4,6 +4,7 @@ import "hk4e/pkg/logger" const ( KcpXorKeyChange = iota + KcpDispatchKeyChange KcpPacketRecvListen KcpPacketSendListen KcpConnForceClose @@ -38,20 +39,24 @@ func (k *KcpConnectManager) eventHandle() { logger.LOG.Error("conn not exist, convId: %v", event.ConvId) continue } - flag, ok := event.EventMessage.(string) + key, ok := event.EventMessage.([]byte) if !ok { logger.LOG.Error("event KcpXorKeyChange msg type error") continue } - if flag == "ENC" { - k.kcpKeyMapLock.Lock() - k.kcpKeyMap[event.ConvId].encKey = k.secretKey - k.kcpKeyMapLock.Unlock() - } else if flag == "DEC" { - k.kcpKeyMapLock.Lock() - k.kcpKeyMap[event.ConvId].decKey = k.secretKey - k.kcpKeyMapLock.Unlock() + k.kcpKeyMapLock.Lock() + k.kcpKeyMap[event.ConvId] = key + k.kcpKeyMapLock.Unlock() + case KcpDispatchKeyChange: + // 首包加密XOR密钥切换 + key, ok := event.EventMessage.([]byte) + if !ok { + logger.LOG.Error("event KcpXorKeyChange msg type error") + continue } + k.dispatchKeyLock.Lock() + k.dispatchKey = key + k.dispatchKeyLock.Unlock() case KcpPacketRecvListen: // 收包监听 k.connMapLock.RLock() diff --git a/pkg/random/hk4e_ec2b.go b/pkg/random/hk4e_ec2b.go index c408bb71..973e49bc 100644 --- a/pkg/random/hk4e_ec2b.go +++ b/pkg/random/hk4e_ec2b.go @@ -13,7 +13,7 @@ type Ec2b struct { temp []byte } -func LoadKey(b []byte) (*Ec2b, error) { +func LoadEc2bKey(b []byte) (*Ec2b, error) { if len(b) < 4+4+16+4+2048 { return nil, fmt.Errorf("invalid ec2b key") } @@ -88,10 +88,8 @@ func (e *Ec2b) Key() []byte { return b } -func (e *Ec2b) Xor(data []byte) { - for i := 0; i < len(data); i++ { - data[i] ^= e.temp[i%4096] - } +func (e *Ec2b) XorKey() []byte { + return e.temp } func keyScramble(key []byte) { diff --git a/pkg/random/hk4e_mt19937.go b/pkg/random/hk4e_mt19937.go index 0a3604a2..06cac309 100644 --- a/pkg/random/hk4e_mt19937.go +++ b/pkg/random/hk4e_mt19937.go @@ -84,8 +84,6 @@ func (b *KeyBlock) Seed() uint64 { return b.seed } -func (b *KeyBlock) Xor(data []byte) { - for i := 0; i < len(data); i++ { - data[i] ^= b.data[i%4096] - } +func (b *KeyBlock) XorKey() [4096]byte { + return b.data } diff --git a/pkg/random/hk4e_test.go b/pkg/random/hk4e_test.go index 68abb289..f2892119 100644 --- a/pkg/random/hk4e_test.go +++ b/pkg/random/hk4e_test.go @@ -2,38 +2,24 @@ package random import ( "fmt" - "os" "testing" ) func TestKey(t *testing.T) { - fmt.Println("hw") + dispatchEc2b := NewEc2b() + dispatchEc2bData := dispatchEc2b.Bytes() + dispatchEc2bSeed := dispatchEc2b.Seed() + _ = dispatchEc2bData - //dispatchEc2b := NewEc2b() - keyBin, err := os.ReadFile("./static/dispatchSeed.bin") - if err != nil { - panic(err) - } - dispatchEc2b, err := LoadKey(keyBin) - if err != nil { - panic(err) - } - dispatchBin := dispatchEc2b.Bytes() - dispatchSeed := dispatchEc2b.Seed() - _ = dispatchBin + dispatchXorKey := dispatchEc2b.XorKey() gateDispatchEc2b := NewEc2b() - gateDispatchEc2b.SetSeed(dispatchSeed) + gateDispatchEc2b.SetSeed(dispatchEc2bSeed) - dispatchKey := make([]byte, 4096) - dispatchEc2b.Xor(dispatchKey) + gateDispatchXorKey := gateDispatchEc2b.XorKey() - gateDispatchKey := make([]byte, 4096) - gateDispatchEc2b.Xor(gateDispatchKey) - - gateXorKey := make([]byte, 4096) keyBlock := NewKeyBlock(uint64(11468049314633205968)) - keyBlock.Xor(gateXorKey) + gateXorKey := keyBlock.XorKey() - fmt.Println("end") + fmt.Println(dispatchXorKey, gateDispatchXorKey, gateXorKey) } diff --git a/pkg/random/random.go b/pkg/random/random.go index 039fc3cc..5010ab15 100644 --- a/pkg/random/random.go +++ b/pkg/random/random.go @@ -10,6 +10,10 @@ func init() { rand.Seed(time.Now().UnixNano()) } +func GetTimeRand() *rand.Rand { + return rand.New(rand.NewSource(time.Now().UnixNano())) +} + func GetRandomStr(strLen int) (str string) { baseStr := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" for i := 0; i < strLen; i++ {