3

所以,首先,我想指出,我知道这些东西从来都不是万无一失的,如果付出足够的努力,任何事情都可能被打破。

但是:假设我将一个软件交给某人(我已经编写)并让他们运行它。我想验证他们得到的结果。我正在考虑使用某种加密/哈希来验证他们是否已经运行它并获得了令人满意的结果。

我也不希望结果是“可伪造的”(尽管我知道,如果有足够的努力来打破它等等......)。因此,这意味着,如果我使用散列,我不能只使用“是”的散列和“否”的散列(因为这意味着散列将只是 2 个选项之一 - 很容易伪造)。

我希望该工具的用户将一些东西交还给我(例如可能是一封电子邮件),一些尽可能小的东西(例如,我不想在一行一行的日志中拖网)。

您将如何实施?我可能没有解释最伟大的事情,但希望你能明白我想做的事情的要点。

如果有人以前实现过这种事情,任何指针都将不胜感激。

这个问题更多的是关于“如何实现”而不是专门询问代码,所以如果我错过了一个重要的标签,请随时编辑!

4

6 回答 6

3

我在这里粘贴您的一条评论,因为它触及了问题的核心:

嗨,埃里克。我应该指出,该工具不会公开发布,它将进入受信任用户的选择列表。被拆卸的工具不是问题。我对加密并不在意,我需要做的就是能够验证他们是否运行了特定的进程并得到了合法的结果。该工具会验证东西,所以我不希望他们只是假设某些东西工作正常而不运行该工具。

所以基本上,我们要防范的威胁是懒惰的用户,他们将无法运行该进程并简单地说“是的,安迪,我运行了它!”。这不是太难解决,因为这意味着我们不需要一个密码学牢不可破的系统(这很幸运,因为无论如何在这种情况下这是不可能的!) - 我们所需要的只是一个可以破解它的系统用户需要付出更多的努力,而不仅仅是遵循规则和运行流程。

最简单的方法是获取一些不固定且易于验证的项目,然后对它们进行哈希处理。例如,您的响应消息可能是:

  • 系统日期/时间
  • 主机名
  • 用户名
  • 测试结果
  • HASH(系统日期/时间|主机名|用户名|测试结果)

同样,这在密码学上并不安全——任何知道算法的人都可以伪造答案——但只要这样做比实际运行进程更麻烦,你应该没问题。包含系统日期/时间可以防止天真的重播攻击(只是发送与上次相同的答案),这应该足够了。

于 2010-07-05T00:39:58.433 回答
3

我认为您正在寻找的是不可否认性。你是对的,在这里散列是不够的——你必须在“完成的工作”上查看某种加密和数字签名,可能是PKI。这是一个相当广泛的领域,我会说你需要身份验证和完整性验证(例如Piskvor做到了,他当时也是这样的)。

鸟瞰,主要流程是这样的:

在用户的计算机上:

  • 运行进程
  • 获取结果,添加时间戳等。
  • 加密,使用你的公钥
  • 使用用户的私钥进行签名(您可能需要某种方式在此处识别用户 - 密码、智能卡、生物识别等)
  • 发送到您的服务器

在您的服务器上:

  • 使用用户的公钥验证签名
  • 使用您的私钥解密
  • 根据需要处理

当然,这将带您进入公钥基础设施这个复杂而美妙的世界;但如果操作正确,您将有一个相当好的保证,即事件实际上是按照日志显示的方式发生的。

于 2010-07-01T12:15:22.107 回答
2

您如何获取程序的输出(“是”或“否”?),并将其与随机数连接,然后包含该字符串的哈希?

因此,您最终会得到用户向您发送类似以下内容的信息:

YES-3456234
b23603f87c54800bef63746c34aa9195

这意味着将有大量独特的哈希,尽管只有两个可能的输出。

然后你就可以验证了md5("YES-3456234") == "b23603f87c54800bef63746c34aa9195"

如果用户没有足够的技术来弄清楚如何生成 md5 哈希,这应该足够了。

更好的解决方案是连接另一个(硬编码,“秘密”)盐以生成散列,但将此盐排除在输出之外。

现在你有:

YES-3456234
01428dd9267d485e8f5440ab5d6b75bd

你可以验证

md5("YES-3456234" + "secretsalt") == "01428dd9267d485e8f5440ab5d6b75bd"

这意味着即使用户足够聪明地生成自己的 md5 哈希,他也无法在不知道秘密盐的情况下伪造输出。

当然,如果他足够聪明,他可以从你的程序中提取盐分。

如果需要更防弹的东西,那么您正在研究正确的加密签名生成,我只会向您推荐 Piskvor 的答案,因为我没有什么有用的补充:)

于 2010-07-01T12:14:44.140 回答
1

值得注意的是,您并不是真的在寻找加密

“不可否认”的答案几乎是在金钱上,但你真正需要保证你的消息来自哪里是安全地签署消息。是否有人可以拦截和阅读您的消息并不重要,只要他们不能在您不知情的情况下篡改它。

在发送明文信息之前,我已经实现了类似的东西——因为它不是机密的——但是混淆的签名机制意味着我们可以(合理地)确信该消息是由我们的客户端软件生成的。

请注意,如果应用程序位于其他人的硬件上,您基本上永远无法保证安全性 - 但安全性从来不是关于“确定性”,而是关于“信心” - 您是否有足够的信心满足您的业务需求,消息没有被篡改?

于 2010-07-01T14:22:56.650 回答
1

理论上,这可以通过使用某种私有盐和散列算法(基本上是数字签名)来实现。该程序有一个私有盐,它在散列之前添加到输入中。私有意味着用户无权访问它,但是您确实知道盐。

用户将他的结果和程序生成的签名发送给您。因此,您现在可以通过检查 if 来确认结果hash(result + private_salt) == signature。如果不是,则结果是伪造的。

在实践中这几乎是不可能的,因为你不能对用户隐藏盐。这与这个问题中讨论的问题基本相同:如何在代码中隐藏密钥?

于 2010-07-01T12:18:38.253 回答
1

您可以使应用程序成为他们无法访问其源代码或访问其运行的服务器的 Web 应用程序。然后您的应用程序可以记录其活动,并且您可以信任这些日志。

一旦用户手中有一个可执行程序,那么任何东西都可以被伪造。

于 2010-07-01T14:17:05.140 回答