通过哈希/加密验证某些内容已“完成”

时间:2010-07-01 11:55:23

标签: c# encryption verification

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

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

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

我希望该工具的用户可以将某些东西交回给我(例如可能是电子邮件中),尽可能小的东西(例如,我不希望通过日志的行和行进行拖网)

你将如何实现这一目标?我可能没有解释最伟大的事情,但希望你能得到我想要做的事情的要点。

如果有人之前已经实现过这种事情,那么任何指针都会非常感激。

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

6 个答案:

答案 0 :(得分:3)

我认为你要找的是non-repudiation。你是对的,这里的哈希是不够的 - 你必须在“完成的工作”上研究某种加密和数字签名,可能是PKI。这是一个相当广泛的领域,我会说你需要身份验证和完整性验证(例如 Piskvor 这样做,他在 这个方式做到了时间)。

从鸟瞰图来看,主流将是这样的:

在用户的计算机上:

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

在您的服务器上:

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

当然,这可以让您进入复杂而精彩的公共密钥基础设施世界;但是如果做得正确的话,你可以很好地保证事件的实际发生方式与你的日志显示方式相同。

答案 1 :(得分:3)

我在这里粘贴你的一条评论,因为它涉及到问题的核心:

  

嗨,埃里克。我应该指出   该工具没有出去   公开地,它会去选择   可信用户列表。工具正在   拆卸不是问题。我不是   所有人都对加密感到困扰   我需要做的是能够验证   他们运行了一个特定的过程并获得了一个   合法的结果。该工具验证   东西,所以我不希望它们只是   假设某些东西工作正常   不要运行该工具。

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

最简单的方法是使用一些不常数且易于验证的项目,并对其进行哈希处理。例如,您的回复消息可能是:

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

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

答案 2 :(得分:2)

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

因此,您最终会向用户发送以下内容:

YES-3456234
b23603f87c54800bef63746c34aa9195

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

然后您可以验证md5("YES-3456234") == "b23603f87c54800bef63746c34aa9195"

如果用户的技术不足以弄清楚如何生成md5哈希,那就足够了。

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

现在你有:

YES-3456234
01428dd9267d485e8f5440ab5d6b75bd

你可以验证

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

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

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

如果需要更加防弹,那么你正在寻找正确的加密签名生成,我只会将你推荐给Piskvor's answer,因为我没有什么有用的东西可以添加到其中:)

答案 3 :(得分:1)

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

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

在实践中,这几乎是不可能的,因为您无法隐藏用户的盐。这与此问题中讨论的问题基本相同:How do you hide secret keys in code?

答案 4 :(得分:1)

您可以将应用程序设置为无法访问源代码的Web应用程序,也可以访问运行它的服务器。然后您的应用程序可以记录其活动,您可以信任这些日志。

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

答案 5 :(得分:1)

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

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

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

请注意,如果应用程序位于其他人的硬件上,您基本上不能保证安全性 - 但安全性绝不是“确定性”,而是“信心” - 您是否有足够的信心 / em>为了您的业务需求,邮件没有被篡改?