mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-12 22:42:26 +08:00
协议密钥动态随机生成
This commit is contained in:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user