协议密钥动态随机生成

This commit is contained in:
huangxiaolei
2022-11-28 23:36:57 +08:00
parent 362ca86130
commit 746435cf3c
22 changed files with 173 additions and 172 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
<EFBFBD><EFBFBD>lt1L <09><>ܟ<EFBFBD>.<15>\<5C>pXP<58><50>"ƀ(<28>a<><61><EFBFBD>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
<EFBFBD><EFBFBD>lt1L <09><>ܟ<EFBFBD>.<15>\<5C>pXP<58><50>"ƀ(<28>a<><61><EFBFBD>

View File

@@ -1,6 +1,7 @@
package region package region
import ( import (
"hk4e/pkg/random"
"os" "os"
"hk4e/pkg/endec" "hk4e/pkg/endec"
@@ -32,23 +33,16 @@ func LoadRsaKey() (signRsaKey []byte, encRsaKeyMap map[string][]byte, pwdRsaKey
return signRsaKey, encRsaKeyMap, pwdRsaKey return signRsaKey, encRsaKeyMap, pwdRsaKey
} }
func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp) { func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) {
dispatchKey, err := os.ReadFile("key/dispatchKey.bin") dispatchEc2b := random.NewEc2b()
if err != nil { dispatchEc2bData := dispatchEc2b.Bytes()
logger.LOG.Error("open dispatchKey.bin error: %v", err) dispatchXorKey := dispatchEc2b.XorKey()
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
}
// RegionCurr // RegionCurr
regionCurr := new(proto.QueryCurrRegionHttpRsp) regionCurr := new(proto.QueryCurrRegionHttpRsp)
regionCurr.RegionInfo = &proto.RegionInfo{ regionCurr.RegionInfo = &proto.RegionInfo{
GateserverIp: kcpAddr, GateserverIp: kcpAddr,
GateserverPort: uint32(kcpPort), GateserverPort: uint32(kcpPort),
SecretKey: dispatchSeed, SecretKey: dispatchEc2bData,
} }
// RegionList // RegionList
customConfigStr := ` customConfigStr := `
@@ -62,7 +56,7 @@ func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *pr
} }
` `
customConfig := []byte(customConfigStr) customConfig := []byte(customConfigStr)
endec.Xor(customConfig, dispatchKey) endec.Xor(customConfig, dispatchXorKey)
serverList := make([]*proto.RegionSimpleInfo, 0) serverList := make([]*proto.RegionSimpleInfo, 0)
server := &proto.RegionSimpleInfo{ server := &proto.RegionSimpleInfo{
Name: "os_usa", Name: "os_usa",
@@ -73,8 +67,8 @@ func InitRegion(kcpAddr string, kcpPort int) (*proto.QueryCurrRegionHttpRsp, *pr
serverList = append(serverList, server) serverList = append(serverList, server)
regionList := new(proto.QueryRegionListHttpRsp) regionList := new(proto.QueryRegionListHttpRsp)
regionList.RegionList = serverList regionList.RegionList = serverList
regionList.ClientSecretKey = dispatchSeed regionList.ClientSecretKey = dispatchEc2bData
regionList.ClientCustomConfigEncrypted = customConfig regionList.ClientCustomConfigEncrypted = customConfig
regionList.EnableLoginPc = true regionList.EnableLoginPc = true
return regionCurr, regionList return regionCurr, regionList, dispatchEc2b
} }

View File

@@ -2,7 +2,6 @@ package app
import ( import (
"context" "context"
"github.com/nats-io/nats.go"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
@@ -26,20 +25,6 @@ func Run(ctx context.Context, configFile string) error {
_ = controller.NewController(db) _ = 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) c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for { for {

View File

@@ -2,6 +2,8 @@ package controller
import ( import (
"encoding/base64" "encoding/base64"
"encoding/binary"
"github.com/nats-io/nats.go"
"net/http" "net/http"
"strconv" "strconv"
@@ -28,7 +30,26 @@ func NewController(dao *dao.Dao) (r *Controller) {
r.dao = dao r.dao = dao
r.regionListBase64 = "" r.regionListBase64 = ""
r.regionCurrBase64 = "" 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() r.signRsaKey, r.encRsaKeyMap, r.pwdRsaKey = region.LoadRsaKey()
regionCurrModify, err := pb.Marshal(regionCurr) regionCurrModify, err := pb.Marshal(regionCurr)
if err != nil { if err != nil {

View File

@@ -35,7 +35,7 @@ func Run(ctx context.Context, configFile string) error {
forwardManager := forward.NewForwardManager(protoMsgInput, protoMsgOutput, kcpEventInput, kcpEventOutput, netMsgInput, netMsgOutput) forwardManager := forward.NewForwardManager(protoMsgInput, protoMsgOutput, kcpEventInput, kcpEventOutput, netMsgInput, netMsgOutput)
forwardManager.Start() forwardManager.Start()
messageQueue := mq.NewMessageQueue(netMsgInput, netMsgOutput) messageQueue := mq.NewMessageQueue(netMsgInput, netMsgOutput, kcpEventInput)
messageQueue.Start() messageQueue.Start()
defer messageQueue.Close() defer messageQueue.Close()

View File

@@ -1,7 +1,7 @@
package forward package forward
import ( import (
"os" "hk4e/pkg/random"
"runtime" "runtime"
"sync" "sync"
"time" "time"
@@ -48,12 +48,14 @@ type ForwardManager struct {
// kcpConv -> headMeta // kcpConv -> headMeta
convHeadMetaMap map[uint64]*ClientHeadMeta convHeadMetaMap map[uint64]*ClientHeadMeta
convHeadMetaMapLock sync.RWMutex convHeadMetaMapLock sync.RWMutex
secretKeyBuffer []byte // kcpConv -> seed
kcpEventInput chan *net.KcpEvent convSeedMap map[uint64]uint64
kcpEventOutput chan *net.KcpEvent convSeedMapLock sync.RWMutex
regionCurr *proto.QueryCurrRegionHttpRsp kcpEventInput chan *net.KcpEvent
signRsaKey []byte kcpEventOutput chan *net.KcpEvent
encRsaKeyMap map[string][]byte regionCurr *proto.QueryCurrRegionHttpRsp
signRsaKey []byte
encRsaKeyMap map[string][]byte
} }
func NewForwardManager( func NewForwardManager(
@@ -70,6 +72,7 @@ func NewForwardManager(
r.userIdConvMap = make(map[uint32]uint64) r.userIdConvMap = make(map[uint32]uint64)
r.convAddrMap = make(map[uint64]string) r.convAddrMap = make(map[uint64]string)
r.convHeadMetaMap = make(map[uint64]*ClientHeadMeta) r.convHeadMetaMap = make(map[uint64]*ClientHeadMeta)
r.convSeedMap = make(map[uint64]uint64)
r.kcpEventInput = kcpEventInput r.kcpEventInput = kcpEventInput
r.kcpEventOutput = kcpEventOutput r.kcpEventOutput = kcpEventOutput
return r return r
@@ -97,23 +100,21 @@ func (f *ForwardManager) kcpEventHandle() {
EventId: net.KcpPacketSendListen, EventId: net.KcpPacketSendListen,
EventMessage: "Disable", EventMessage: "Disable",
} }
// 登录成功 通知GS初始化相关数据 seed, exist := f.getSeedByConvId(event.ConvId)
userId, exist := f.getUserIdByConvId(event.ConvId)
if !exist { if !exist {
logger.LOG.Error("can not find userId by convId") logger.LOG.Error("can not find seed by convId")
continue continue
} }
headMeta, exist := f.getHeadMetaByConvId(event.ConvId) keyBlock := random.NewKeyBlock(seed)
if !exist { xorKey := keyBlock.XorKey()
logger.LOG.Error("can not find client head metadata by convId") key := make([]byte, 4096)
continue 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: case net.KcpConnCloseNotify:
// 连接断开通知 // 连接断开通知
userId, exist := f.getUserIdByConvId(event.ConvId) userId, exist := f.getUserIdByConvId(event.ConvId)
@@ -139,6 +140,7 @@ func (f *ForwardManager) kcpEventHandle() {
} }
f.deleteAddrByConvId(event.ConvId) f.deleteAddrByConvId(event.ConvId)
f.deleteHeadMetaByConvId(event.ConvId) f.deleteHeadMetaByConvId(event.ConvId)
f.deleteSeedByConvId(event.ConvId)
case net.KcpConnEstNotify: case net.KcpConnEstNotify:
// 连接建立通知 // 连接建立通知
addr, ok := event.EventMessage.(string) addr, ok := event.EventMessage.(string)
@@ -183,15 +185,9 @@ func (f *ForwardManager) kcpEventHandle() {
func (f *ForwardManager) Start() { 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() f.signRsaKey, f.encRsaKeyMap, _ = region.LoadRsaKey()
// region // 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 f.regionCurr = regionCurr
// kcp事件监听 // kcp事件监听
go f.kcpEventHandle() go f.kcpEventHandle()
@@ -226,12 +222,6 @@ func (f *ForwardManager) sendNetMsgToGameServer() {
if getPlayerTokenRsp == nil { if getPlayerTokenRsp == nil {
continue continue
} }
// 改变解密密钥
f.kcpEventInput <- &net.KcpEvent{
ConvId: protoMsg.ConvId,
EventId: net.KcpXorKeyChange,
EventMessage: "DEC",
}
// 返回数据到客户端 // 返回数据到客户端
resp := new(net.ProtoMsg) resp := new(net.ProtoMsg)
resp.ConvId = protoMsg.ConvId resp.ConvId = protoMsg.ConvId
@@ -249,29 +239,30 @@ func (f *ForwardManager) sendNetMsgToGameServer() {
if playerLoginRsp == nil { if playerLoginRsp == nil {
continue continue
} }
// 改变加密密钥 // 返回数据到客户端
f.kcpEventInput <- &net.KcpEvent{ resp := new(net.ProtoMsg)
ConvId: protoMsg.ConvId, resp.ConvId = protoMsg.ConvId
EventId: net.KcpXorKeyChange, resp.CmdId = cmd.PlayerLoginRsp
EventMessage: "ENC", 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
} }
// 开启发包监听 headMeta, exist := f.getHeadMetaByConvId(protoMsg.ConvId)
f.kcpEventInput <- &net.KcpEvent{ if !exist {
ConvId: protoMsg.ConvId, logger.LOG.Error("can not find client head metadata by convId")
EventId: net.KcpPacketSendListen, continue
EventMessage: "Enable",
} }
go func() { netMsg := new(cmd.NetMsg)
// 保证kcp事件已成功生效 netMsg.UserId = userId
time.Sleep(time.Millisecond * 50) netMsg.EventId = cmd.UserLoginNotify
// 返回数据到客户端 netMsg.ClientSeq = headMeta.seq
resp := new(net.ProtoMsg) f.netMsgInput <- netMsg
resp.ConvId = protoMsg.ConvId logger.LOG.Info("send to gs user login ok, ConvId: %v, UserId: %v", protoMsg.ConvId, netMsg.UserId)
resp.CmdId = cmd.PlayerLoginRsp
resp.HeadMessage = f.getHeadMsg(protoMsg.HeadMessage.ClientSequenceId)
resp.PayloadMessage = playerLoginRsp
f.protoMsgInput <- resp
}()
case cmd.SetPlayerBornDataReq: case cmd.SetPlayerBornDataReq:
// 玩家注册请求 // 玩家注册请求
if connState != ConnAlive { if connState != ConnAlive {
@@ -480,6 +471,25 @@ func (f *ForwardManager) deleteHeadMetaByConvId(convId uint64) {
f.convHeadMetaMapLock.Unlock() 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 { func (f *ForwardManager) ChangeGateOpenState(isOpen bool) bool {
f.kcpEventInput <- &net.KcpEvent{ f.kcpEventInput <- &net.KcpEvent{

View File

@@ -4,8 +4,11 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"fmt"
"hk4e/dispatch/controller" "hk4e/dispatch/controller"
"hk4e/pkg/httpclient" "hk4e/pkg/httpclient"
"hk4e/pkg/random"
"math/rand"
"strconv" "strconv"
"strings" "strings"
@@ -69,15 +72,16 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
rsp.Uid = tokenVerifyRsp.PlayerID rsp.Uid = tokenVerifyRsp.PlayerID
// TODO 不同的token // TODO 不同的token
rsp.Token = "xxx" 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 要确定一下新注册的号这个值该返回什么 // TODO 要确定一下新注册的号这个值该返回什么
rsp.AccountType = 1
rsp.IsProficientPlayer = true rsp.IsProficientPlayer = true
rsp.SecretKeySeed = 11468049314633205968
rsp.SecurityCmdBuffer = f.secretKeyBuffer
rsp.PlatformType = 3 rsp.PlatformType = 3
rsp.ChannelId = 1 rsp.ChannelId = 1
rsp.CountryCode = "US" rsp.CountryCode = "US"
rsp.ClientVersionRandomKey = "c25-314dd05b0b5f"
rsp.RegPlatform = 3 rsp.RegPlatform = 3
addr, exist := f.getAddrByConvId(convId) addr, exist := f.getAddrByConvId(convId)
if !exist { if !exist {
@@ -87,7 +91,6 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
split := strings.Split(addr, ":") split := strings.Split(addr, ":")
rsp.ClientIpStr = split[0] rsp.ClientIpStr = split[0]
if req.GetKeyId() != 0 { if req.GetKeyId() != 0 {
// pre check
logger.LOG.Debug("do hk4e 2.8 rsa logic") logger.LOG.Debug("do hk4e 2.8 rsa logic")
keyId := strconv.Itoa(int(req.GetKeyId())) keyId := strconv.Itoa(int(req.GetKeyId()))
encPubPrivKey, exist := f.encRsaKeyMap[keyId] 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) logger.LOG.Error("parse client seed base64 error: %v", err)
return nil 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) clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey)
if err != nil { if err != nil {
logger.LOG.Error("rsa dec error: %v", err) 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) logger.LOG.Error("parse client seed to uint64 error: %v", err)
return rsp return rsp
} }
seedUint64 := uint64(11468049314633205968) ^ clientSeedUint64 timeRand := random.GetTimeRand()
serverSeedUint64 := timeRand.Uint64()
f.setSeedByConvId(convId, serverSeedUint64)
seedUint64 := serverSeedUint64 ^ clientSeedUint64
seedBuf := new(bytes.Buffer) seedBuf := new(bytes.Buffer)
err = binary.Write(seedBuf, binary.BigEndian, seedUint64) err = binary.Write(seedBuf, binary.BigEndian, seedUint64)
if err != nil { if err != nil {
@@ -149,6 +148,12 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
} }
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc) rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)
rsp.Sign = base64.StdEncoding.EncodeToString(seedSign) rsp.Sign = base64.StdEncoding.EncodeToString(seedSign)
// 开启发包监听
f.kcpEventInput <- &net.KcpEvent{
ConvId: convId,
EventId: net.KcpPacketSendListen,
EventMessage: "Enable",
}
} }
return rsp return rsp
} }
@@ -170,6 +175,7 @@ func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (
rsp.IsUseAbilityHash = true rsp.IsUseAbilityHash = true
rsp.AbilityHashCode = 1844674 rsp.AbilityHashCode = 1844674
rsp.GameBiz = "hk4e_global" rsp.GameBiz = "hk4e_global"
rsp.ClientDataVersion = f.regionCurr.RegionInfo.ClientDataVersion rsp.ClientDataVersion = f.regionCurr.RegionInfo.ClientDataVersion
rsp.ClientSilenceDataVersion = f.regionCurr.RegionInfo.ClientSilenceDataVersion rsp.ClientSilenceDataVersion = f.regionCurr.RegionInfo.ClientSilenceDataVersion
rsp.ClientMd5 = f.regionCurr.RegionInfo.ClientDataMd5 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.ResVersionConfig = f.regionCurr.RegionInfo.ResVersionConfig
rsp.ClientVersionSuffix = f.regionCurr.RegionInfo.ClientVersionSuffix rsp.ClientVersionSuffix = f.regionCurr.RegionInfo.ClientVersionSuffix
rsp.ClientSilenceVersionSuffix = f.regionCurr.RegionInfo.ClientSilenceVersionSuffix rsp.ClientSilenceVersionSuffix = f.regionCurr.RegionInfo.ClientSilenceVersionSuffix
rsp.IsScOpen = false rsp.IsScOpen = false
rsp.RegisterCps = "mihoyo" rsp.RegisterCps = "mihoyo"
rsp.CountryCode = "US" rsp.CountryCode = "US"

View File

@@ -1,8 +1,11 @@
package mq package mq
import ( import (
"encoding/binary"
"hk4e/common/config" "hk4e/common/config"
"hk4e/gate/net"
"hk4e/pkg/logger" "hk4e/pkg/logger"
"hk4e/pkg/random"
"hk4e/protocol/cmd" "hk4e/protocol/cmd"
"github.com/nats-io/nats.go" "github.com/nats-io/nats.go"
@@ -18,7 +21,7 @@ type MessageQueue struct {
cmdProtoMap *cmd.CmdProtoMap 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) r = new(MessageQueue)
conn, err := nats.Connect(config.CONF.MQ.NatsUrl) conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
if err != nil { if err != nil {
@@ -43,7 +46,16 @@ func NewMessageQueue(netMsgInput chan *cmd.NetMsg, netMsgOutput chan *cmd.NetMsg
go func() { go func() {
for { for {
natsMsg := <-keyNatsMsgChan 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,
}
} }
}() }()

View File

@@ -3,7 +3,6 @@ package net
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"os"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@@ -14,11 +13,6 @@ import (
"hk4e/pkg/random" "hk4e/pkg/random"
) )
type KcpXorKey struct {
encKey []byte
decKey []byte
}
type KcpConnectManager struct { type KcpConnectManager struct {
openState bool openState bool
connMap map[uint64]*kcp.UDPSession connMap map[uint64]*kcp.UDPSession
@@ -36,10 +30,10 @@ type KcpConnectManager struct {
kcpSendListenMap map[uint64]bool kcpSendListenMap map[uint64]bool
kcpSendListenMapLock sync.RWMutex kcpSendListenMapLock sync.RWMutex
// key // key
dispatchKey []byte dispatchKey []byte
secretKey []byte dispatchKeyLock sync.RWMutex
kcpKeyMap map[uint64]*KcpXorKey kcpKeyMap map[uint64][]byte
kcpKeyMapLock sync.RWMutex kcpKeyMapLock sync.RWMutex
// conv短时间内唯一生成 // conv短时间内唯一生成
convGenMap map[uint64]int64 convGenMap map[uint64]int64
convGenMapLock sync.RWMutex convGenMapLock sync.RWMutex
@@ -57,7 +51,7 @@ func NewKcpConnectManager(protoMsgInput chan *ProtoMsg, protoMsgOutput chan *Pro
r.kcpRawSendChanMap = make(map[uint64]chan *ProtoMsg) r.kcpRawSendChanMap = make(map[uint64]chan *ProtoMsg)
r.kcpRecvListenMap = make(map[uint64]bool) r.kcpRecvListenMap = make(map[uint64]bool)
r.kcpSendListenMap = 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) r.convGenMap = make(map[uint64]int64)
return r return r
} }
@@ -65,17 +59,7 @@ func NewKcpConnectManager(protoMsgInput chan *ProtoMsg, protoMsgOutput chan *Pro
func (k *KcpConnectManager) Start() { func (k *KcpConnectManager) Start() {
go func() { go func() {
// key // key
var err error = nil k.dispatchKey = make([]byte, 4096)
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
}
// kcp // kcp
port := strconv.FormatInt(int64(config.CONF.Hk4e.KcpPort), 10) port := strconv.FormatInt(int64(config.CONF.Hk4e.KcpPort), 10)
listener, err := kcp.ListenWithOptions("0.0.0.0:"+port, nil, 0, 0) 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.connMap[convId] = conn
k.connMapLock.Unlock() k.connMapLock.Unlock()
k.kcpKeyMapLock.Lock() k.kcpKeyMapLock.Lock()
k.kcpKeyMap[convId] = &KcpXorKey{ k.dispatchKeyLock.RLock()
encKey: k.dispatchKey, k.kcpKeyMap[convId] = k.dispatchKey
decKey: k.dispatchKey, k.dispatchKeyLock.RUnlock()
}
k.kcpKeyMapLock.Unlock() k.kcpKeyMapLock.Unlock()
go k.recvHandle(convId) go k.recvHandle(convId)
kcpRawSendChan := make(chan *ProtoMsg, 10000) kcpRawSendChan := make(chan *ProtoMsg, 10000)

View File

@@ -42,7 +42,7 @@ func (k *KcpConnectManager) decodeBinToPayload(data []byte, convId uint64, kcpMs
logger.LOG.Error("kcp xor key not exist, convId: %v", convId) logger.LOG.Error("kcp xor key not exist, convId: %v", convId)
return return
} }
endec.Xor(data, xorKey.decKey) endec.Xor(data, xorKey)
k.decodeRecur(data, convId, kcpMsgList) 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) logger.LOG.Error("kcp xor key not exist, convId: %v", kcpMsg.ConvId)
return return
} }
endec.Xor(bin, xorKey.encKey) endec.Xor(bin, xorKey)
return bin return bin
} }

View File

@@ -4,6 +4,7 @@ import "hk4e/pkg/logger"
const ( const (
KcpXorKeyChange = iota KcpXorKeyChange = iota
KcpDispatchKeyChange
KcpPacketRecvListen KcpPacketRecvListen
KcpPacketSendListen KcpPacketSendListen
KcpConnForceClose KcpConnForceClose
@@ -38,20 +39,24 @@ func (k *KcpConnectManager) eventHandle() {
logger.LOG.Error("conn not exist, convId: %v", event.ConvId) logger.LOG.Error("conn not exist, convId: %v", event.ConvId)
continue continue
} }
flag, ok := event.EventMessage.(string) key, ok := event.EventMessage.([]byte)
if !ok { if !ok {
logger.LOG.Error("event KcpXorKeyChange msg type error") logger.LOG.Error("event KcpXorKeyChange msg type error")
continue continue
} }
if flag == "ENC" { k.kcpKeyMapLock.Lock()
k.kcpKeyMapLock.Lock() k.kcpKeyMap[event.ConvId] = key
k.kcpKeyMap[event.ConvId].encKey = k.secretKey k.kcpKeyMapLock.Unlock()
k.kcpKeyMapLock.Unlock() case KcpDispatchKeyChange:
} else if flag == "DEC" { // 首包加密XOR密钥切换
k.kcpKeyMapLock.Lock() key, ok := event.EventMessage.([]byte)
k.kcpKeyMap[event.ConvId].decKey = k.secretKey if !ok {
k.kcpKeyMapLock.Unlock() logger.LOG.Error("event KcpXorKeyChange msg type error")
continue
} }
k.dispatchKeyLock.Lock()
k.dispatchKey = key
k.dispatchKeyLock.Unlock()
case KcpPacketRecvListen: case KcpPacketRecvListen:
// 收包监听 // 收包监听
k.connMapLock.RLock() k.connMapLock.RLock()

View File

@@ -13,7 +13,7 @@ type Ec2b struct {
temp []byte temp []byte
} }
func LoadKey(b []byte) (*Ec2b, error) { func LoadEc2bKey(b []byte) (*Ec2b, error) {
if len(b) < 4+4+16+4+2048 { if len(b) < 4+4+16+4+2048 {
return nil, fmt.Errorf("invalid ec2b key") return nil, fmt.Errorf("invalid ec2b key")
} }
@@ -88,10 +88,8 @@ func (e *Ec2b) Key() []byte {
return b return b
} }
func (e *Ec2b) Xor(data []byte) { func (e *Ec2b) XorKey() []byte {
for i := 0; i < len(data); i++ { return e.temp
data[i] ^= e.temp[i%4096]
}
} }
func keyScramble(key []byte) { func keyScramble(key []byte) {

View File

@@ -84,8 +84,6 @@ func (b *KeyBlock) Seed() uint64 {
return b.seed return b.seed
} }
func (b *KeyBlock) Xor(data []byte) { func (b *KeyBlock) XorKey() [4096]byte {
for i := 0; i < len(data); i++ { return b.data
data[i] ^= b.data[i%4096]
}
} }

View File

@@ -2,38 +2,24 @@ package random
import ( import (
"fmt" "fmt"
"os"
"testing" "testing"
) )
func TestKey(t *testing.T) { func TestKey(t *testing.T) {
fmt.Println("hw") dispatchEc2b := NewEc2b()
dispatchEc2bData := dispatchEc2b.Bytes()
dispatchEc2bSeed := dispatchEc2b.Seed()
_ = dispatchEc2bData
//dispatchEc2b := NewEc2b() dispatchXorKey := dispatchEc2b.XorKey()
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
gateDispatchEc2b := NewEc2b() gateDispatchEc2b := NewEc2b()
gateDispatchEc2b.SetSeed(dispatchSeed) gateDispatchEc2b.SetSeed(dispatchEc2bSeed)
dispatchKey := make([]byte, 4096) gateDispatchXorKey := gateDispatchEc2b.XorKey()
dispatchEc2b.Xor(dispatchKey)
gateDispatchKey := make([]byte, 4096)
gateDispatchEc2b.Xor(gateDispatchKey)
gateXorKey := make([]byte, 4096)
keyBlock := NewKeyBlock(uint64(11468049314633205968)) keyBlock := NewKeyBlock(uint64(11468049314633205968))
keyBlock.Xor(gateXorKey) gateXorKey := keyBlock.XorKey()
fmt.Println("end") fmt.Println(dispatchXorKey, gateDispatchXorKey, gateXorKey)
} }

View File

@@ -10,6 +10,10 @@ func init() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
} }
func GetTimeRand() *rand.Rand {
return rand.New(rand.NewSource(time.Now().UnixNano()))
}
func GetRandomStr(strLen int) (str string) { func GetRandomStr(strLen int) (str string) {
baseStr := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" baseStr := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for i := 0; i < strLen; i++ { for i := 0; i < strLen; i++ {