3

我目前正在制作游戏。我在内部构建了日志记录工具,并且有一般、日志、异常、发送、接收、调试等消息类型。

发送和接收日志包含原始日志信息,因此它们确实包含我通过网络发送的内容。

该游戏使用客户端-服务器模型并使用 SSL 连接,因此无法更改网络信息。但是对于日志记录,我会将文本记录为纯文本,这显然会造成麻烦。此外,我计划简单地屏蔽(通过 * 的)任何个人信息(如密码等)

不过我有几个担心:

  • 客户端程序包含与 SSL 一起使用的信任库,服务器的主机名/IP 和端口也不是真正的秘密。因此,如果一个人知道通过网络发送什么,那么他就可以表现得像客户一样,对吧?
  • 如果一个人可以看到客户端发送和接收的内容,那么他​​可能能够非常轻松地制作一个机器人。(游戏是回合制2D游戏,所以我认为只要依靠所有的网络数据你应该可以玩游戏。鼠标不需要任何技巧。)

总而言之:我如何仍然记录所有信息并将其写入文件,但没有其他人能够读取、修改或以任何方式使用它?

非常感谢所有评论,我也希望就如何实施这样的系统提出具体建议。

问候。

4

3 回答 3

6

如果您担心加密服务器上的数据,那么最简单的解决方案是像Truecrypt这样的全分区加密程序- 如果有人窃取机器/硬盘驱动器,这将保护服务器数据。

如果您在客户端机器上加密数据,那么这意味着加密密钥也必须在客户端机器上的某个位置(即使它在主内存中)。继续对日志信息进行加密或混淆,以使用户更难以阅读它,但请注意,如果用户付出足够的努力,他仍然能够阅读它。也就是说,混淆数据的最佳方法是使用永远不会保存到磁盘的密钥对其进行加密——例如,当用户登录时,向他们发送一个新的加密密钥,他们的客户端应用程序将使用该密钥来加密日志数据;在您的服务器上,记录您发送给客户端的密钥以及 UTC 时间戳。使用未加密的时间戳存储日志,以便当用户的客户端应用程序发送日志数据时,您将知道使用哪个密钥来解密它。显然用户可以轻松更改时间戳,但这相当于用户只是从他们的机器中删除日志数据(这是您无法阻止的);同时,用户很难弄清楚使用什么密钥来加密数据,因此用户读取或伪造日志数据并不容易(但同样,如果用户付出足够的努力,用户可以读取/伪造日志数据进去)。

您可以采取措施来混淆内存中的加密密钥,例如将其存储在多个部分中。例如,假设您使用的是 AES 128,您可以将密钥存储在两个 64 位块中,然后在加密数据之前将它们连接起来,然后在完成后立即从内存中擦除连接的密钥。或者,您可以将两个异或的 128 位密钥存储在一起,一旦完成,再次从内存中擦除异或密钥。专门的用户仍然可以找出密钥,但这会使他们更加困难。

您可以采取的另一个步骤是使用除 AES 之外的加密算法,例如,任何其他 AES 决赛入围者,如 Twofish 或 Serpent(不要实现自己的加密算法,最好广播您正在使用强算法,例如AES 比您使用的是弱混淆算法)。请记住混淆加密库的类和方法名称,以使用户更难弄清楚您正在使用什么加密算法。(如果您要编译为机器代码,这会更有效 - 如果您使用的是 Java,这可能不值得,因为用户可以简单地反编译您的代码并使用您自己的解密代码来解密日志文件。)

在确定玩家是人类还是机器人方面,即使是预算比你大得多的游戏也无法可靠地做到这一点 - 你真正能做的就是引导用户或在他们展示时向他们发送某种验证码“类似机器人”的行为,但这并不是万无一失的,你真的应该赞成不要惹恼合法用户而不是引导机器人。

于 2013-05-21T19:20:59.417 回答
2

你能做的不多。如果客户端是用 Java 编写的,则很容易进行逆向工程,或者使用 AspectJ 之类的东西来监视客户端正在向网络写入的内容。对于写入日志系统的任何数据也是如此,即使它最终是加密的。

于 2013-05-21T19:07:00.330 回答
0

我和你有同样的需求。一些叫做“maybeWeCouldStealAVa”的人写了一个很棒的实现: 如何附加到 AES 加密文件

我已经确认它可以工作,但是当我在每一行的末尾“flush()”时,我会丢失消息的最后一部分——最多 16 个字节——直到下一条消息被写入。我可以在每一行的末尾关闭(),因为这似乎是编写填充的唯一方法。但至少它不需要读取整个文件以便能够附加到它。

于 2014-09-22T05:41:38.803 回答