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

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

  •  
  •   linuxsteam · 13 天前 · 2582 次点击

    需求

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

    个人调研

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

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

    个人结论

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

    • 非对称加密:

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

    • 动态消息认证码( HMAC )

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

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

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

    • 时间戳验证

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

    求助

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

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

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

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

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

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

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

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

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

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