我希望能够创建一个文件,将其分发给最终用户,但阻止他们对文件进行修改。
现在,显然,我实际上无法阻止任何人修改文件 - 所以我的方法是检测并拒绝文件是否被修改。
我的意图是生成文件内容的加盐哈希并将其附加到文件中。读取时,在读取文件的其余部分之前验证哈希。这样做的缺点是我必须在读取文件的可执行文件中分发固定的“盐”。显然我可以在某种程度上混淆它,但这仍然感觉像是一个薄弱环节。
有没有更好的方法来解决这类问题?
我希望能够创建一个文件,将其分发给最终用户,但阻止他们对文件进行修改。
现在,显然,我实际上无法阻止任何人修改文件 - 所以我的方法是检测并拒绝文件是否被修改。
我的意图是生成文件内容的加盐哈希并将其附加到文件中。读取时,在读取文件的其余部分之前验证哈希。这样做的缺点是我必须在读取文件的可执行文件中分发固定的“盐”。显然我可以在某种程度上混淆它,但这仍然感觉像是一个薄弱环节。
有没有更好的方法来解决这类问题?
您想将数字签名附加到您的文档。这是一个已经被广泛研究的领域。简而言之,您可以相当肯定地确保文件未被篡改,但您无法阻止用户对其进行篡改。
(与音乐行业的比较并不完全相关,因为他们也想阻止人们复制文件,这是一个更难的问题。)
如果您的应用程序在用户的机器上运行,他们总是可以修补二进制文件,因此甚至不进行验证,从而使您的所有辛勤工作变得无用:-)
甚至可以通过嗅探流量绕过服务器端解决方案。因此,您需要将它们组合起来并使用 SSL。然后他们只是像上面那样修补了二进制文件,就这样。因此,您使用各种措施来混淆您的二进制文件,并且您的用户会推出像 IDA PRO 这样的反汇编程序。
如果我处于你的位置,我会问自己的问题是“如果我与用户进行军备竞赛,我会赢吗?”。如果答案是否定的,那么我不会浪费我的时间。
使用数字签名。签名是使用公私钥加密的哈希值。您的应用程序仅包含公钥。该密钥用于解密散列,然后验证散列。要在文件修改后“纠正”散列,用户必须计算新的散列,用私钥对其进行加密,并在文件末尾替换旧的散列。问题:他没有私钥。私钥不在您的应用程序中。私钥不会随您的应用程序一起提供。您的应用程序只有公共应用程序。如果他用公共的加密它,它不会用公共的解密,所以这是没有用的。私钥在您的计算机上,没有人可以访问它。
如果您想要 100% 的解决方案,则不是。看看电影和音乐行业。他们已经尝试并失败了很多年:)
我认为您的解决方案已经足够好了。为了使修改文件变得更加困难,您可以对其进行加密,但是他们无法读取它,因此只有在这是一个好的限制时它才会起作用。
对于您对散列散列的关注... 好的做法是制作散列并使用私钥-公钥对对其进行加密。你只需要分发公钥。这样,他们可以阅读它,但不能修改它或创建新的。
我建议按照 JesperE 的建议使用数字签名。这个过程是标准的,你会发现很多例子来演示它。
即使用户修补他们自己的二进制文件以确保他们编辑的文件副本正常工作,它的编辑副本仍然无法在未修补的机器上工作。阻止这种编辑的目的是什么?
顺便说一句,与纯文本文件相比,用户不太容易编辑二进制文件。此外,如果你给他们一个二进制文件,用户不太容易感到恼火,而不是你给他们一个带有校验和的文本文件,假设他们有一些合法的理由希望编辑它,并且可以通过查看文件来告诉他们如果您没有添加校验和或其他任何内容,这样做会很容易。
根据您要保护的文件类型,您可以使用一些文档管理工具。Adobe PDF 有这方面的工具。此外,如果您将应用程序托管在应用程序服务器或 Web 服务器上,则用户无法访问和修改代码。这样,您可以在服务器端拥有一个哈希数据库,其中包含您想要保护的文件。
当然,保护仅取决于用户想要(或可以)投入多少时间和精力来破坏保护。
这就是 md5 哈希和 CRC 的用途,这就是为什么您检查从 Internet 下载的文件与他们的 md5 文件,以确保它没有在途中被劫持。
无论如何,我认为 Roddy 使用 C++,所以我可以推荐 Boost::CRC 它非常快速且开销很小,您也不需要以这种方式加密文件
谁是您的用户以及他们尝试更改文件的难度。如果您的用户能够找到您添加到哈希中的盐,那么他们可能会在您的代码中找到一个公钥,将其更改为他们自己生成的公钥,并使用他们的私钥计算修改后文件的签名。我会去混淆盐。
另一种选择是某种在线系统,它增加了巨大的复杂性,而且通常无论如何都是可以破解的。
看看 HMAC,了解一种使用“盐”的编码方法,就像你在想的那样(盐被称为键)。