V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Game Engines
Unreal Engine
MyCryENGINE
linuxsteam
V2EX  ›  游戏开发

Web 游戏通信时如何保证数据完整性(防止用户篡改修改结果)?

  •  
  •   linuxsteam · 9 天前 · 2516 次点击

    需求

    小弟想研究自己写一个 FlyBrid 的游戏,将游戏得到的分数对用户进行奖励。需要保证用户无法篡改数据实现“自定义”分数去获取奖励。

    个人调研

    目前上网搜索了很多资料,貌似通信方式可以选择 WebSocket 、Socket 、HTTP 。 基于以上通信方式搜索到资料,实现需求的大致提供的思路就是:

    • 传输层:服务端和客户端通信采用 非对称加密 + 动态消息认证码( HMAC )+ 时间戳验证
    • 客户端:前端代码混淆
    • 实现方式:尽量使用服务端下发命令,而不是采用客户端最终提交结果方式去处理

    个人结论

    个人理解这种方式还是不太安全,只是提高了攻击方的门槛。 例如:

    • 非对称加密:

    最终公钥前端都能拿到,然后用户可以提取该公钥,对篡改的数据进行加密。

    • 动态消息认证码( HMAC )

    个人理解使用该方式的话,服务端和客户端每一次通信都生成一次 HMAC ,为下次通信使用,并且保证该 HMAC 有效时间足够短。

    在 FlyBird 游戏实际应用可能就是,服务端生成管道时候,会生成下一次通信需要的 HMAC ,并且设置有消息为生成管道的时间间隔

    基于以上逻辑,我理解还是可以写程序模拟进行操作,欺骗服务端达到修改分数的目的。(就是我自己这关都过不去)

    • 时间戳验证

    跟上面动态消息认证码的攻破方式是类似的。

    求助

    小弟没有做过游戏后端开发思维是有些局限的,不知道大家有没有成本较低实现数据防篡改的办法

    第 1 条附言  ·  9 天前
    感谢大家的批评建议与思路。小弟就不一一回复了
    26 条回复    2025-04-15 13:44:42 +08:00
    laikick
        1
    laikick  
       9 天前
    先用非对称加密实现吧. 没必要过度设计.
    seers
        2
    seers  
       9 天前 via Android
    你逻辑写在 so ,然后 ollvm 一下,基本上可以杜绝 99%的脚本 boy 了
    linuxsteam
        3
    linuxsteam  
    OP
       9 天前
    @laikick 我也不想过度设计,但是发放的奖励是有成本的。。所以得谨慎一点。。嘿嘿
    sentinelK
        4
    sentinelK  
       9 天前   ❤️ 17
    你的思路和你的需求差一万八千里。导致你钻牛角尖里面不能自拔。
    你要先明确你到底要什么:“需要保证用户无法篡改数据实现“自定义”分数去获取奖励”

    所以你的核心是“反作弊”(或者让作弊的成本高于作弊的收益),而不是“提高客户端破解难度”和“保障通信安全”。

    所以你真正需要的是业务伪装与游戏行为校验。

    1 、上传的分数与其游戏时间是否匹配?
    2 、上传的分数与其操作逻辑是否匹配?
    3 、其达成的里程碑与其总游戏时长是否匹配?
    4 、是否处于高危网络环境?
    5 、是否处于高危客户端?
    6 、是真实的客户端请求么?

    基于此,又可以衍生众多的校验逻辑与策略。而且策略是动态可修改的。这样就可以无限放大作弊的成本。

    安全运钞的核心不是用多么坚固的运钞车,而是取消纸钞,线上转账。仅此而已。
    wqhui
        5
    wqhui  
       9 天前
    楼上正解,不存在百分百的防护,只需要让作弊成本大于作弊收益就没人搞你
    NessajCN
        6
    NessajCN  
       9 天前
    @linuxsteam 那你发奖励前人工审核呗
    linuxsteam
        7
    linuxsteam  
    OP
       9 天前
    @sentinelK 您说的对,我调查发现这个游戏中的通信防作弊,不是无懈可击的。只能提高作弊门槛,也就是您说的这些业务算法。
    @NessajCN 人工审核哪是程序员追求的目标 哈哈哈
    不过前期对大额数据,做小批次拦截 人工介入
    sentinelK
        8
    sentinelK  
       9 天前   ❤️ 1
    而且如果游戏的“收益”是有偿的,那其实你需要建立一个奖励发放模型。
    当发放的奖励超过你模型允许的区间时,不管对方是不是作弊,都要当作产品事故来回溯与二次验证。

    而不是试图弄一个完美的机制来确定每一个取钱的人都是善意的。
    colinlikepotatos
        9
    colinlikepotatos  
       9 天前   ❤️ 1
    我们这么做的。关键事件上报到 clickhouse 。发放的时候再回溯,从时间,行为链上去判断,超过一定的指标就人工审核,就算是真作弊了 做到这个份上就认了,除非大规模作弊。作弊是避免不了的。愿意花大心思的人,就随他去了。。。只要不超过预期值。就不应该花更多的心思去处理作弊的问题,会误杀很多正常的玩家
    ndxxx
        10
    ndxxx  
       9 天前
    你这个需求太简单了。本地时间,上传时间,分数,游戏时间,就这四个,非对称加密之后在服务端简单手写个算法校验一下,就完了。
    点进来还以为是 upd 包的高频小包数据的服务端校验,这里面门道就多了。
    linuxsteam
        11
    linuxsteam  
    OP
       9 天前
    @ndxxx 嘿嘿,我这个是新手问题
    @colinlikepotatos 你这个专业,我是个 oneman 怕是实现不过来 哈哈哈哈
    guchengzhihuan
        12
    guchengzhihuan  
       9 天前
    @colinlikepotatos 我大概理解你的意思,比如游戏设计好了一个账号每天最多赚 10 块钱,就算他用脚本把这 10 块钱跑满把 10 块钱给他就行了。如果有他一天能跑 100 块了超出了你的设计范围,管他是不是脚本跑的必须凉拌他。
    ndxxx
        13
    ndxxx  
       9 天前
    @ndxxx #10 upd -> udp 手滑了
    InDom
        14
    InDom  
       9 天前   ❤️ 1
    简单, 你只需要实现一个必死的结局, 然后游戏开始前就决定该用户的奖励上限, 达到上限以后直接给发必死结局即可.

    不死 === 作弊
    死了 === 成果挽回损失
    linuxsteam
        15
    linuxsteam  
    OP
       9 天前
    @InDom 只能说三个字 666
    Building
        16
    Building  
       9 天前
    做不到百分百防作弊的,能做到网游也不会有这么多外挂了
    h1298841903
        17
    h1298841903  
       9 天前
    AI 作弊怎么办?
    mohyz
        18
    mohyz  
       9 天前
    战斗校验
    rekulas
        19
    rekulas  
       9 天前
    参考 dota2 lol ,做成 cs 同步模式,可以尽可能的避免外挂
    是工作量多多了去了,对小游戏来说完全没必要,其实就做一些简单加密校验都够了,大概率没人有兴趣来破解。。。
    lisxour
        20
    lisxour  
       9 天前
    最简单有效的办法就是服务器演算 ,但说实话你这种类型的小游戏就算了吧,随便搞点加密上去得了,视觉识别能把很多游戏都秒了,而且都有很多成熟方案了
    UnluckyNinja
        21
    UnluckyNinja  
       9 天前 via Android
    也基本没有玩小游戏必给奖励的(就算给也是给鸡毛蒜皮的虚拟奖励,直接全发都不亏那种),尤其是实体奖励,最后都是走抽选系统控制总奖池大小。形式上有个参与感就够了
    picone
        22
    picone  
       9 天前   ❤️ 1
    你这是 H5 游戏?我想起我之前玩的一个 web3 游戏,是打飞机然后最终按照打的排名分数给奖励,真金白银的 ETH 。

    因为游戏过程是客户端计算的,所以只能验证上报分数,上报分数他设计了一套巧妙的签名,还放 wasm 了,最后还是被我破解了。毕竟有钱🐎。https://picone.github.io/2023/05/12/exploit-stark-figter.html
    xuhuanzy
        23
    xuhuanzy  
       9 天前 via Android   ❤️ 1
    首先,客户端的一切都是不可信的
    EMMMMMMMMM
        24
    EMMMMMMMMM  
       9 天前 via Android
    @picone 666
    kekeabab
        25
    kekeabab  
       9 天前
    最简单粗暴的办法,不要给用户客户端就好了,采用“远程游玩”的方式,反正你这个游戏也不需要多少性能。
    linuxsteam
        26
    linuxsteam  
    OP
       9 天前
    @picone 666
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1521 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 100ms · UTC 16:48 · PVG 00:48 · LAX 09:48 · JFK 12:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.