【问题标题】:Verifying that something has been "done" through hashes/encryption通过散列/加密验证某事已“完成”
【发布时间】:2026-01-07 17:20:03
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 什么是阻止恶意用户反汇编你的程序,编辑它以产生他们想要的任何结果,然后你的加密逻辑向你发送加密选择的明文?如果您的前提是客户端不可靠,那么不要编写一个依赖来自客户端的数据的安全系统。
  • 另外,请注意,在未经客户同意和不知道消息内容的情况下,使用有关客户的加密信息“打电话回家”的软件可能是非法的。我不是律师;隐私法因国家/地区而异。在进一步深入之前,您可能应该咨询国际隐私问题专家。
  • 最后,我要指出的是,您已经声明要使用加密,但没有明确说明威胁。加密是一种用于减轻威胁的漏洞的技术。 威胁到底是什么? 是窃听,还是敌对用户,还是什么?如果加密实际上并不能减轻您所面临的威胁,请不要使用加密;使用一些有效的技术
  • 嗨,埃里克。我应该指出,该工具不会公开发布,它将进入受信任用户的选择列表。被拆卸的工具不是问题。我对加密并不在意,我需要做的就是能够验证他们是否运行了特定的进程并得到了合法的结果。该工具会验证东西,所以我不希望他们只是假设某些东西工作正常而不运行该工具。
  • 关于打电话回家,它不一定必须这样做,我可能不想每次运行时都检查结果(而是每隔一段时间)。当我要求时,用户可以通过电子邮件将其发送给我(这是一个工作环境)。发送的数据不会是敏感的(显然),所以虽然我提到加密也许我不应该有,但我真的只是写下我脑海中可能有远程帮助的所有内容,以获得尽可能多的批评和尽可能的想法(比如你现在给出的):)

标签: c# encryption verification


【解决方案1】:

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

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

在用户的计算机上:

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

在您的服务器上:

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

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

【讨论】:

  • 谢谢皮斯克沃尔。澄清一下,我对特定用户运行它并不感兴趣,只是运行它并获得了有效的输出。
  • @AndyC:好吧,你可以为安装创建一个密钥对,而不是一个用户 - 如果你关心它在哪里运行,那就是。
  • 感谢 Piskvor 的回答!
【解决方案2】:

我在这里粘贴你的一个 cmets,因为它触及了问题的核心:

嗨,埃里克。我应该指出 该工具不会消失 在公开场合,它将进入精选 受信任的用户列表。工具是 拆机不是问题。我不是 真的很担心加密,所有 我需要做的是能够验证 他们运行了一个特定的过程并得到了一个 合法的结果。该工具验证 东西,所以我不希望他们只是 假设某事工作正常并且 不运行该工具。

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

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

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

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

【讨论】:

    【解决方案3】:

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

    所以你最终会得到用户向你发送类似的东西:

    YES-3456234
    b23603f87c54800bef63746c34aa9195
    

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

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

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

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

    现在你有:

    YES-3456234
    01428dd9267d485e8f5440ab5d6b75bd
    

    你可以验证一下

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

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

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

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

    【讨论】:

    • 您必须将您的盐 (3456234) 与哈希一起发送,对吗?否则,您将如何验证结果? (md5("YES-" . $nobodyknowswhatshouldbehere)) 或者,将其作为共享机密保存在用户和您身边。
    • 是的,你会发送输出、盐和哈希。这是通过(不是非常)默默无闻的安全性。
    • 共享的秘密盐也会遇到同样的“只有两个哈希”问题。
    • 但是共享秘密盐,随机盐可以解决这两个问题!已编辑。
    • 感谢 Blorgbeard 的回答!
    【解决方案4】:

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

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

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

    【讨论】:

    • 此外,生成的唯一哈希值与可能的输出一样多 - 一个代表“是”,一个代表“否”,就像在 OP 的问题中一样。
    • 没错,你必须添加另一个服务器提供的随机 salt ala CRAM 来解决这个问题。
    【解决方案5】:

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

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

    【讨论】:

    • 对不起,我可能应该说,但转换为网络应用程序所需的工作量会令人望而却步(因为该应用程序已经编写好了,我正在寻找的将被实现为更新)。不过感谢您的回答!
    【解决方案6】:

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

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

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

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

    【讨论】:

    • 是的,这正是我想要的。我不介意正在阅读的信息,只要它不能在我不知情的情况下被伪造或更改。
    • 那么您只需要消息签名。困难在于混淆客户端代码以阻止人们使用它来签署自己的消息(这永远不会 100% 可行,但您可以将其复杂到足以成为合理的威慑)。