【问题标题】:Methods for encrypting an archive in C++在 C++ 中加密存档的方法
【发布时间】:2011-06-16 04:38:05
【问题描述】:

我正在编写一个游戏,它将在一些 xml 文档以及资源文件中包含大量信息(配置、一些内容等)。这将使我自己和其他人更容易编辑程序,而无需编辑实际的 C++ 文件,也无需重新编译。

但是,随着程序开始增长,与程序位于同一目录中的文件也会增加。所以我想把它们放在一个文件存档中(因为它们主要是文本,所以压缩效果很好)。

我的问题是:压缩所有文件会更容易吗?

  1. 为其设置密码(如受密码保护的 ZIP),然后在程序需要时提供密码
  2. 使用 Crypto++ 或类似工具加密存档
  3. 稍微修改文件头作为“临时”加密,并在文件加载时修复文件头

我认为数字 1 和 2 是相似的,但我找不到任何关于 zlib 是否可以处理受密码保护的档案的信息。

另外请注意,我不希望在程序使用存档时将存档中的文件“解压缩”到文件夹中。它应该只在系统的内存中。

【问题讨论】:

  • 为什么需要加密这些东西?
  • 它需要加密,因为我不希望任何人对其进行编辑或逆向工程。
  • 如果数据和可执行代码在用户的机器上,那么你的加密不会阻止一个坚定的黑客。
  • AFAIK,许多游戏使用自己的虚拟文件系统,通常只用于只读文件。要保护已保存的游戏,您可以使用 CRC。

标签: c++ compression encryption password-protection


【解决方案1】:

我认为您误解了加密带来的可能性。

只要程序在不受信任的主机上执行,就无法保证任何事情。

您最多可以让某人对代码进行逆向工程变得困难(加密、代码混淆)或极其困难(自修改代码、调试/挂钩检测),但您无法防止破解。而通过互联网,只要一个人破解它,所有人都可以使用它。

这同样适用于防止个人篡改配置。无论采用何种方法(CRC、哈希 --> 顺便说一句,加密并不是为了防止篡改),只要有足够的时间和手段(和动机),仍然可以对其进行逆向工程。

保证配置不受篡改的唯一方法是将其存储在您控制的位置(服务器),对其进行签名(非对称)并让程序检查签名。但即使那样,它也不会阻止有人提供一个补丁,让你的程序使用用户提供的(未签名的)配置文件运行......

你知道最坏的情况吗?人们可能会更喜欢破解版,因为它摆脱了所有“安全”措施的负担,运行速度更快……

注意:是的,这是非法的,但让我们务实...

注意:关于动机,你在保护程序方面越聪明,它对黑客的吸引力就越大 --> 这对他们来说就像是脑筋急转弯!

那么您如何提供安全的服务呢?

  • 您需要信任执行程序的人
  • 您需要信任存储配置的人

只有在您提供瘦客户端并在您信任的服务器上执行所有操作时才能做到这一点……即使这样,您也很难确保没有人在您的服务器中找到您没想到的门关于。

在您的立场上,我只是确保检测到对配置的轻微篡改(将其视为恶意并确保在运行任何东西之前验证数据)。毕竟文件损坏的可能性是一样的,如果损坏的配置文件意味着损坏的客户端机器,那就要付出惨痛的代价:)

【讨论】:

  • 虽然你没有回答我的问题,但它确实给了我很多思考,你指出了我自己会忽略的事情。但你是对的。在我的游戏中,我有一个名为 debug 的“可选文件”。如果存在,里面会有调试信息,例如:禁用打补丁服务,让你不打补丁也能玩。或者,另一个示例:如果存档不存在,则允许游戏从文件文件夹而不是存档中读取。这对于快速创建内容非常有用,但我不希望有人使用它。所以我要把它放在服务器端。
【解决方案2】:

如果我必须在您的三个选项中进行选择,我会选择 Crypto++,因为它非常适合 C++ iostream。

但是:你是

  • 将数据序列化为 XML
  • 压缩它
  • 加密

全部在内存中,然后又回来了。我真的会重新考虑这个选择。为什么不使用例如。 SQLite 将所有数据存储在基于文件的数据库中(SQLite 不需要任何外部数据库进程)?

可以通过各种扩展(SEESQLCipher)添加加密。它安全、快速且完全透明。

你没有得到压缩,但是再一次,通过使用 SQLite 而不是 XML,这不会是一个问题(或者我认为)。

【讨论】:

  • 我考虑过一个数据库,但由于有许多不同类型的文件(不仅仅是 xml 配置),我认为将 .png 存储到数据库中是没有意义的。此外,如果我需要编辑多个或单个文件,我可以:解压缩文件,编辑它,然后重新打包。我认为数据库会更复杂一些。
【解决方案3】:

为其设置密码(如受密码保护的 ZIP),然后在程序需要时提供密码

首先,除非您要向用户询问密码,否则您不能这样做。如果该加密密钥存储在代码中,请不要押注某个坚定的逆向工程师会找到它并解密存档。

一个重要的规则是:你不能在你的软件中存储加密密钥,因为如果你这样做了,那么使用加密有什么意义呢?我可以找到你的钥匙。

现在,到其他点。 zlib does not support encryption,正如他们所指出的,PKZip is rather broken anyway。我怀疑如果你这么想找到一个,你可能会找到一个能够处理加密的 zip/压缩库。 (ZipArchive 我相信可以处理 Zip+AES,但您需要为此付费)。

但我支持丹尼尔刚刚在我的屏幕上显示的答案。为什么?除非用户提供某种形式的令牌(密码、智能卡等),否则加密/压缩不会给您带来任何好处,而这些令牌(密码、智能卡等)并不存在于您编译的二进制文件或相关文件中。同样,如果您不使用大量磁盘空间,为什么要压缩?

【讨论】:

  • 我以前从未使用过 SQLite,所以如果您不同意,请提及,但是当我提出存档的想法时,是因为我可以将类似的文件组织到他们自己的存档中(bgm、系统、 map1, map2) 这将使更新变得简单,因为所有更新程序所要做的就是删除现有文件并用更新的版本替换它。使用 SQLite,所有文件的整体组织和更新过程都会更加混乱。
  • “你不能在你的软件中存储加密密钥,因为如果你这样做了,使用加密有什么意义?”。非对称加密提供篡改保护:存档可以使用(公共)解密密钥读取,但不可写入。
  • @MSalters 为真,但随后所述数据必须保持固定或从原始供应商(即私有加密密钥的持有者)重新提供。您不能阻止用户阅读该存档,我认为(如果我错了,我可以告诉我,我可以随时删除它)OP 的意思是。
  • 同样,攻击者替换二进制文件中的公钥也无法阻止您。不容易,但可行。当然,在逆向工程的那个级别,他们可能能够绕过任何受保护的功能。这里的重点是,加密作为一种方法不会阻止坚定的逆向工程师。永远。
猜你喜欢
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
相关资源
最近更新 更多