1

...我在这里阅读了一些讨论各种方法的主题,并且只是在寻找对我们提出的解决方案的一些反馈。在其中一个线程中发布了一条评论,推荐了一个听起来很棒的公钥/私钥,这就是我们的想法......

客户端 - 1. 密钥存储在使用第 3 方工具加密的 Flash swf 中。2. 高分与高分值一起散列(例如:md5 ('ourSecretKey' + 200)) 3. 该值通过 AMF 与高分 (200) 一起发送到服务器上的 PHP 脚本

服务器端 - 1. 服务器接收数据并对传递的高分 (200) + 密钥(存储在服务器和 Flash 中的“ourSecretKey”)进行哈希处理,并检查传递的哈希值是否匹配它允许高分进入,否则失败。

我知道这不是一个万无一失的解决方案,但这可以接受吗?我的意思是,对于一个简单的在线 Flash 游戏来说,这对于高分形式是否足够安全?想法?

先感谢您!

4

7 回答 7

7

对于一个可笑的短值(即:值 < 64 个字符),由于彩虹表攻击,MD5 作为哈希变得无效,并且由于您发送的值将通过网络共享,他们所要做的就是蛮力共享秘密(他们有一个已知的产品可以使用)

因此,那不是公钥私钥。它只是共享的秘密。

另外,请记住,这个共享秘密将在您发送给用户的闪存文件中,这些天并且被简单地反汇编,然后您的“秘密”不再是秘密。

您需要一个具有适当加密签名的更多挑战-响应机制,其中从服务器为每个游戏分配一个新的签名密钥,并且不能使用相同的签名密钥提交多个分数。(为了额外的保护;))

  1. 用户开始游戏。请求签名密钥。(签名密钥是从他们无法访问的另一个密钥产生的)。
  2. 使用签名密钥对分数进行签名,然后发送
  3. 您使用您发送给他们的密钥验证标志的值。
  4. 您丢弃发送给他们的签名密钥。

但是,您仍然存在无法防止实际评分系统被篡改的问题。足够聪明的人可以对您的 SWF 对象进行逆向工程并注入新代码,将分数设置为他们选择的值。

于 2008-11-19T20:45:26.530 回答
4

你的问题的答案是,这取决于。这主要取决于您的游戏的估计受欢迎程度。

从安全角度来看,您的解决方案与以明文形式发送高分一样安全。你在这里所做的被称为默默无闻的安全,根据你听谁的,在某些情况下可能有它的好处。在这种情况下,普通用户可能无法自己破解它。对于拥有一些 l33t h4xx 或技能的人,您不妨以明文形式发送所有内容。如果您只想阻止 Joe,那么这可能就足够了,至少在有人创建一个供 Joe 下载的假客户端之前(这取决于您的游戏的受欢迎程度可能需要几天到永远不会(或者更快,如果它是哇))。

一个更好的解决方案是@Kent Fredric 给出的解决方案。然而,正如它所说,它并不能解决有人创建假客户的问题。解决方案可能是这样的:

  1. 给玩家可以执行的每一个动作一个id。
  2. 将玩家执行的每个动作存储在一个 id 列表中。
  3. 当游戏结束时,对分数、动作列表进行哈希处理,并使用从服务器接收到的公钥对其进行加密。(有关详细信息,请参阅 Kent Fredric 的帖子)
  4. 将加密的哈希(通常称为数字签名)连同分数执行的操作列表一起发送到服务器。
  5. 让服务器根据列表中的动作“玩”游戏。
  6. 验证是否获得了相同的分数。
  7. 验证数字签名是否正确。
  8. 更新服务器高分列表。

这将保证两件事:

  1. 分数来自正确的客户。
  2. 就所玩的游戏而言,得分是正确的。

但是这个方案还有一个严重的缺陷。没有办法知道游戏实际上是真的玩过的。如果客户端受到攻击,列表可能只是发送到服务器的“完美游戏”的预制件。直接篡改评分系统是不可能的,但只要付出足够的努力,某人很可能能够创建一个包含“完美游戏”的动作列表。

但是,它提供了比仅使用 Kent Fredric 帖子中的解决方案更强大的保证。要解决整个问题意味着您必须以某种方式验证客户端。这是非常困难的,因为大多数方法都很容易绕过。

最后,我只需要评论一下您选择的哈希算法:MD5 对于那些仍然生活在九十年代的人来说是一个很棒的哈希算法。对于我们其他人,我推荐 SHA-2 或至少 SHA-1。

于 2008-11-19T22:53:22.107 回答
2

如果您的游戏分布有限,并且没有真正的金钱/赏金让玩家获胜,那么您的原始方案可能就足够了。

使用 SWF Encrypt 可能会使提取密钥变得更加困难,即使在更高级的系统中也可能是一个很好的工具。但是如果你有一个真正的公钥/私钥方案(例如 RSA),这真的是一个有争议的问题,因为公钥不是秘密,它不应该是。为了防止大多数人编辑代码和篡改评分系统,SWF Encrypt 可能是一个足够好的选择。


只是为了让您更加偏执,我还写了以下内容:

与大多数其他类似工具一样,SWF Encrypt 的问题在于它必须仍然可以在(可能已被破坏的)机器上执行脚本。因此,所有信息必须在所述机器上可用。将其与经典的密码学用法进行比较,发送消息:

当您发送加密消息时,您通常信任源和目标,因此它们都具有解密消息的密钥。你不信任的是信使,或者至少你的敌人不会拦截信使。所以快递员没有他们的钥匙,你的信息是安全的。

相反,您的问题是,在您的情况下,您信任目的地(您)而不是来源(客户端),反之亦然。由于您对快递员的信任程度更低,因此您仍然需要来源能够加密消息。因此,源需要拥有所有信息来加密和解密消息才能正常工作。您的问题是您看不到“好”来源和“坏”来源之间的区别。

我的意思是,由于代码必须仍然可以在客户端上运行,因此这样做的信息必须是完全可用的,尽管可能是以模糊的形式。例如,黑客可以创建自己的 ActionScript 编译器,将经过混淆的 ActionScript 代码转换为可读的内容并进行适当的更改。困难但绝对可行。

然而,如果您的分布有限并且没有真正的赏金可赢,那么这种级别的复杂攻击很可能对您来说不是问题。

于 2008-11-20T11:45:35.230 回答
1

Blockquote 最后,我只想评论一下您选择的散列算法:MD5 对那些仍然生活在九十年代的人来说是一个很棒的散列算法。对于我们其他人,我推荐 SHA-2 或至少 SHA-1。

呸,我知道我应该提到 SHA :)

如果我确实使用类似 swf 加密器应用程序来加密 swf 代码,那至少不会使获取存储在 Flash 中的密钥变得更加困难吗?我认为如果没有那个密钥(或者至少没有很容易地得到它),弄清楚什么是用来生成发送到服务器的散列​​将是一个巨大的痛苦。

我在想这样的事情:SWF Encrypt

再次感谢大家的这些答案,这非常有帮助。哦,这只是一个由客户发送给客户的简单 Flash 游戏,在假期打发时间的乐趣。

于 2008-11-20T00:58:03.697 回答
1

Kent 说,我没有看到使用该解决方案的任何优势。作为客户端,我可以请求服务器端创建的密钥。好的,我不能使用它超过一次,但我不必......每次我需要一个时,我都会请求它。

  1. 所以我要求钥匙。
  2. 做我自己的高分
  3. 用键对高分进行散列。
  4. 将高分发送到服务器
  5. 服务器使用提交的密钥来获取高分。
于 2009-02-07T13:06:34.217 回答
1

加密分数的 100% 工作方式只有一种:记录回放。
但不仅仅是任何重播,理想情况下,您应该只记录用户按键和它们之间的空间。这样,即使有人篡改了源或动态地使用RAM,在服务器上播放的回放也会发现问题。
不幸的是,这个解决方案需要大量的工作才能成为可能。为简单起见,您只需手动验证所有分数(或最佳分数),您就会很高兴。尽管如此,您仍然必须避免一些事情:

  • 默认随机生成器,您需要种子生成器,它总是为给定的种子提供相同的随机数;
  • 没有增量计时,抱歉;
  • 自定义三角函数(我不是 100% 确定,我曾经听说它们可以在不同的计算机上给出略有不同的结果);

并且可能更多。
然而,这种防御是牢不可破的。并且需要时间来编码:D。

于 2010-11-02T10:26:08.797 回答
0

相当困难的解决方案 8)。

我曾经实现过这样的系统。虽然它不适用于所有游戏......

你应该在服务器上重玩游戏。当用户玩游戏时——您存储“状态变化”,然后以某种“重播”模式将其提供给您的游戏。

于 2009-05-03T22:32:11.170 回答