这是网络游戏和比赛的经典问题。您的 Flash 代码与用户一起决定游戏的分数。但是用户不可信,Flash 代码在用户的计算机上运行。你是SOL。您无法阻止攻击者伪造高分:
针对您的系统的最简单的攻击是通过代理运行游戏的 HTTP 流量,捕获高分保存,然后以更高的分数重放它。
您可以尝试通过将每个高分存档绑定到游戏的单个实例来阻止此攻击,例如,通过在游戏启动时向客户端发送加密令牌,其外观可能如下所示:
hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))
(您也可以使用会话 Cookie 达到相同的效果)。
游戏代码通过高分保存将此令牌回显到服务器。但是攻击者仍然可以再次启动游戏,获取令牌,然后立即将该令牌粘贴到重播的高分保存中。
因此,接下来,您不仅要提供令牌或会话 cookie,还要提供高分加密会话密钥。这将是一个128位AES密钥,本身使用硬编码到Flash游戏中的密钥进行加密:
hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))
现在,在游戏发布高分之前,它会解密高分加密会话密钥,这可以做到,因为您将高分加密会话密钥解密密钥硬编码到Flash二进制文件中。您可以使用此解密密钥加密高分,以及高分的 SHA1 哈希:
hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))
服务器上的 PHP 代码检查令牌以确保请求来自有效的游戏实例,然后解密加密的高分,检查以确保高分与高分的 SHA1 匹配(如果跳过此步骤,解密将只产生随机的,可能是非常高的高分)。
因此,现在攻击者反编译您的Flash代码并快速找到AES代码,该代码像拇指疼痛一样伸出,尽管即使没有,它也会在15分钟内通过内存搜索和跟踪器进行跟踪(“我知道我在这个游戏中的分数是666,所以让我们在内存中找到666,然后捕获任何触及该值的操作---哦,看, 高分加密代码!”使用会话密钥,攻击者甚至不必运行Flash代码;她抢走了一个游戏启动令牌和一个会话密钥,并可以发回任意高分。
您现在处于大多数开发人员放弃---放弃或花几个月的时间与攻击者打交道的地步:
使用异或操作扰乱 AES 密钥
将键字节数组替换为计算键的函数
在整个二进制文件中散布假密钥加密和高分发布。
这一切都是浪费时间。不言而喻,SSL也不会帮助你;当两个SSL端点之一是邪恶的时,SSL无法保护您。
以下是一些实际上可以减少高分欺诈的事情:
需要登录才能玩游戏,让登录名生成会话 Cookie,并且不允许在同一会话上启动多个未完成的游戏,也不允许同一用户启动多个并发会话。
拒绝持续时间低于有史以来最短真实游戏的游戏会话的高分(对于更复杂的方法,请尝试对持续时间低于平均游戏持续时间少于 2 个标准差的游戏会话进行“隔离”高分)。确保您在服务器端跟踪游戏持续时间。
拒绝或隔离仅玩过一次或两次游戏的登录名的高分,以便攻击者必须为他们创建的每次登录名生成合理外观游戏玩法的“书面记录”。
“心跳”分数在游戏过程中,以便您的服务器在一次游戏的生命周期内看到分数的增长。拒绝不遵循合理分数曲线的高分(例如,从0跳到999999)。
游戏过程中的“快照”游戏状态(例如,弹药量、关卡中的位置等),您以后可以将其与记录的临时分数进行协调。您甚至不必首先检测此数据中的异常;你只需要收集它,然后你可以回去分析它,如果事情看起来很腥。
禁用任何未通过安全检查的用户的帐户(例如,通过提交未通过验证的加密高分)。
请记住,您只是在这里阻止高分欺诈。如果发生,您无能为力。如果你的游戏里有钱,有人会打败你想出的任何系统。目标不是阻止这种攻击;这是为了让进攻更加昂贵,而不仅仅是在比赛中表现出色并击败它。