mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
协议密钥动态随机生成
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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.
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD>lt1L <09><>ܟ<EFBFBD>.<15>\<5C>pXP<58><50>"ƀ(<28>a<><61><EFBFBD>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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++ {
|
||||
|
||||
Reference in New Issue
Block a user