在javascript游戏中,是否可以完全禁止用户篡改javascript?

在javascript游戏中,是否可以完全禁止用户篡改javascript?,javascript,ajax,security,Javascript,Ajax,Security,我开始制作一个在线游戏,其中大部分游戏都是用javascript编写的。从安全角度来看,我想到,使用FireBug等工具,游戏玩家可以轻松地操纵javascript,并做游戏不想做的事情(例如,让角色跳两倍高) 如果我设置了一个功能将分数发布到记分板上,情况会变得更糟。玩家不仅能够获得不准确的分数,而且如果他们知道分数是如何发布到服务器的,那么他们就可以从FireBug构造一个AJAX调用来发布他们想要的任何分数 这个特殊的问题与游戏有关,但核心问题是JavaScript安全性,它可以应用于许多

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

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


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

不,这是绝对不可能的

你可以使用模糊处理,你可以让你的AJAX非常难看,最终,人们最多需要5分钟来绕过你使用的任何客户端安全性


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

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

进行大量检查。如果最大跳转为5个块高,请确保服务器不接受高于5的跳转


当我做游戏时,我会检查每一件事。即使有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}
];
result.security_key = your_over_the_top_complicated_algorithm(result, md5(result));
...
function your_over_the_top_complicated_algorithm(result, seed)
{....}
...
在服务器端,用整个数据包检查
安全密钥
{score:?,epoch\u ms:?}。如果失败,则服务器将返回一条降低激励的消息:“错误。安全密钥不正确。下次发生这种情况时,您的帐户将因作弊而被禁止。”如何防止人们一直创建新帐户超出了此答案的范围,但肯定有非常好的方法可以做到这一点

如何生成安全密钥 生成
安全密钥的代码可以是这样的:

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}
];
result.security_key = your_over_the_top_complicated_algorithm(result, md5(result));
...
function your_over_the_top_complicated_algorithm(result, seed)
{....}
...
现在,
security\u key
是用一个非常模糊和复杂的算法创建的,该算法使用非常长的正则表达式等等。确保任何试图弄清楚它是如何工作的人,至少需要一周的时间来正确理解它(你可以每周彻底更新你的算法,以降低进一步逆向工程的积极性)

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

愚弄 诀窍在于,当作弊者试图确定如何击败这个复杂的算法时,
result
作为一个外部小型散列函数(如
md5
)的引用被传递到某处。但是,外部md5函数实际上是我们自己的修改版本,我们在其中添加了一点代码,这牺牲了
result.epoch_ms
值的历元精度,以存储基于分数的哈希(可能还有result对象中的其他元素)

比如说。 如果
epoch\u ms
等于“
15236564511
”,并且
得分为“
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\u ms
的最后两个数字与基于
分数的简单哈希不匹配时,服务器将返回相同的错误,就像
安全密钥
无效一样。这是误导的一个重要部分

当心 这种方法很难实现。没有权衡。问题是这个谜题的答案隐藏在显而易见的地方。一旦误导失败,有人检查
md5.js
文件并查找
r
的用法,游戏就结束了

还要注意,我只是自己编的,对于这是否足以阻止基于javascript的网络游戏中的作弊者,我个人没有经验。我可能忽略了这种方法的一个巨大弱点。如果您发现了一个弱点,请发表评论,这是一个未开发的想法,所以请注意:)

这在加密技术上根本不安全,就像所有的反作弊系统一样,最终会有人发现它。我想诀窍是用最少的实现努力尽可能地使它变得困难

尽管这是一个相对简单的例子,但有足够的模糊处理、隐写术、严格的禁止政策(作弊者很可能会在第一次尝试时出错)、进一步的改进,以及