协议密钥动态随机生成

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

View File

@@ -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{

View File

@@ -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"