3

我开始制作一个大部分游戏都是用 JavaScript 编写的在线游戏。从安全的角度来看,我想到使用 FireBug 之类的工具,游戏的玩家可以轻松地操纵 javascript 并做游戏不打算做的事情(例如,让角色跳两倍高)。

如果我设置一个功能来将分数发布到记分牌上,情况会变得更糟。玩家不仅可以获得不准确的分数,而且如果他们知道分数是如何发布到服务器的,那么他们可以从 FireBug 构造一个 AJAX 调用来发布他们想要的任何分数。

这个特殊问题与游戏有关,但核心问题是 JavaScript 安全性,它可以应用于许多其他 Web 应用程序。

4

4 回答 4

3

不,这绝对不可能。

你可以使用混淆,你可以让你的 AJAX 变得非常丑陋,最后最多需要 5 分钟的时间来绕过你使用的任何客户端安全性。

您需要检查与服务器端安全相关的任何内容,包括评分。如何做到这一点取决于您的实施。

于 2012-05-03T02:25:33.483 回答
3

如果代码在普通的网络浏览器中运行,则不可能按照您的意愿保护它。但是,您可以验证事件服务器端以确保发生的操作“有意义”,因此用户无法向您发送高分或其他方式。这当然会使您的编程以非平凡的方式复杂化。

于 2012-05-03T02:25:51.593 回答
2

做很多检查。如果最大跳跃高度为 5 格,请确保服务器不接受高于 5 的跳跃。

当我制作游戏时,我会检查每一件事。即使用户有 1% 的可能性会做某事来破解特定的东西,它仍然受到保护。

于 2012-05-03T02:52:20.123 回答
-1

是的,您可以保护您的游戏。例如,让作弊者解决一个使用误导的极其困难的难题。

上下文示例

考虑一个完全依赖于 javascript 的游戏,并且没有服务器端的游戏状态。在游戏过程中,积分被收集,并且在游戏结束时,这些积分被发送到服务器以将玩家置于排行榜上。

排行榜问题

游戏最关键的部分是有人可以监控网络流量,并随心所欲地改变它。可以通过在服务器上保持游戏状态来防止游戏中的所有其他方面,但这超出了我的回答范围。

实施“安全密钥”

考虑到您像这样跟踪 javascript 对象中的点:

results = [
    {score: 12, epoch_ms: 15236543784, security_key: 6b42535e89f7fb1cc5abbe53d267ee0e},
    {score: 4, epoch_ms: 15236542565, security_key: 8af02a3d473d6b9c0a0362cfa59567d8},
    {score: 5, epoch_ms: 15236564511, security_key: 40f6611ff3156d935f420eb746ac897f}
];

在服务器端,security_key检查整个数据包{score: ?, epoch_ms: ?}。如果失败,则从服务器返回一条令人沮丧的消息:“错误。安全密钥不正确。下次发生这种情况,您的帐户将因作弊而被禁止。 ”如何防止人们一直创建新帐户超出了范围这个答案,但绝对有很好的方法可以做到这一点。

如何生成安全密钥

生成的代码security_key可能是这样的:

result.security_key = your_over_the_top_complicated_algorithm(result, md5(result));
...
function your_over_the_top_complicated_algorithm(result, seed)
{....}
...

现在,它security_key是使用非常模糊和复杂的算法创建的,该算法使用非常冗长的正则表达式等。确保任何人试图弄清楚它是如何工作的,至少需要一周的时间才能正确理解它(你可以每周彻底更新你的算法,以抑制任何进一步的逆向工程)。

要使此代码正常工作,您还必须包含一个实现所用哈希算法 ( md5.js) 的现有库,这些哈希的使用也可以嵌入到您的复杂算法中,只要该库是一个单独的文件。

上当了

诀窍是——当作弊者试图确定如何打败那个复杂的算法时——什么时候result作为参考传递给外部缩小的散列函数,比如md5. 但是,外部的 md5 函数实际上是我们自己的修改版本,我们在其中添加了一点代码,这牺牲了result.epoch_ms值的 epoch 的精度来存储基于分数的哈希(可能还有结果对象中的其他元素)。

例如。如果epoch_ms等于 " 15236564511" 并且score是 " 5"。然后,当我们沿线调用某个地方md5(result)以充当我们的顶级复杂功能的种子时。但与此同时,在那个外部 md5 代码中......

 function md5(r)
 {
     ...
     r.epoch_ms=(r.epoch_ms+'').slice(0, -2)+(1234.56*r.score+'').slice(1,3);
     // or obfuscated (to prevent searching for terms like 'epoch_ms'):
     var _0x5da4=["\x65\x70\x6F\x63\x68\x5F\x6D\x73","\x73\x6C\x69\x63\x65","","\x73\x63\x6F\x72\x65"];r[_0x5da4[0]]= (r[_0x5da4[0]]+ _0x5da4[2])[_0x5da4[1]](0,-2)+ (1234.56* r[_0x5da4[3]]+ _0x5da4[2])[_0x5da4[1]](1,3)
     ...
 }

当 的最后两个数字epoch_ms与基于 的简单哈希不匹配时score,服务器将返回与 无效一样的错误security_key。这是误导的重要组成部分。

谨防

这种方法很容易实施。没有取舍。问题是这个难题的解决方案隐藏在显而易见的地方。一旦误导失败,并且有人检查md5.js文件并查找 的用法r,它就“游戏结束”。

另请注意,我只是自己编造的,并没有亲身体验这是否足以阻止基于 javascript 的网页游戏中的作弊者。我可能忽略了这种方法的一个巨大弱点。如果您发现弱点,请发表评论,这是一个不成熟的想法,所以要友善:)

这在密码学上根本不安全,并且与所有反作弊系统一样,最终有人会弄清楚。我想诀窍是用最少的实施工作使其尽可能困难。

尽管这是一个相对简单的示例,但有足够的混淆、隐写术、严格的禁止政策(作弊者很可能在第一次尝试时会犯错误)、进一步的改进和实现的简单性,这似乎是一个很好的额外预防措施拿。使用 md5 函数隐藏代码只是众多变体之一。你可以想出许多不同的方法来误导和抑制潜在的作弊者。

它有点像你家的加固门。他们不能再只是踢门进去,而是需要花更多的时间才能进去。

于 2017-07-26T18:32:01.900 回答