验证某些事情已经“完成”通过哈希/加密

发布于 2024-09-08 00:17:50 字数 477 浏览 8 评论 0原文

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

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

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

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

您将如何实施这一点?我可能还没有解释清楚,但希望你能明白我想做的事情的要点。

如果有人以前实现过此类事情,任何指示将不胜感激。

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

So, to start off, I want to point out that I know that these things are never fool-proof and if enough effort is applied anything can be broken.

But: Say I hand a piece of software to someone (that I have written) and get them to run it. I want to verify the result that they get. I was thinking of using some sort of encryption/hash that I can use to verify that they've run it and obtained a satisfactory result.

I also don't want the result to be "fakeable" (though again, I know that if enough effort to break it is applied etc etc...). This means therefore, that if I use a hash, I can't just have a hash for "yes" and a hash for "no" (as this means the hash is going to be only one of 2 options - easily fakeable).

I want the user of the tool to hand something back to me (in possibly an email for example), something as small as possible (so for example, I don't want to be trawling through lines and lines of logs).

How would you go about implementing this? I possibly haven't explained things the greatest, but hopefully you get the gist of what I want to do.

If anyone has implemented this sort of thing before, any pointers would be much appreciated.

This question is more about "how to implement" rather than specifically asking about code, so if I've missed an important tag please feel free to edit!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爺獨霸怡葒院 2024-09-15 00:17:50

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

鸟瞰图,主要流程如下:

在用户计算机上:

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

在您的服务器上:

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

过程当然,这将带您进入复杂而美妙的世界那就是公钥基础设施;但如果做得正确,您将可以很好地保证事件确实按照日志显示的方式发生。

I think what you're looking for is non-repudiation. You're right, a hash won't suffice here - you'd have to look into some kind of encryption and digital signature on the "work done", probably PKI. This is a pretty wide field, I'd say you'll need both authentication and integrity verification (e.g. Piskvor did that, and he did it this way at that time).

To take a bird's eye view, the main flow would be something like this:

On user's computer:

  • run process
  • get result, add timestamp etc.
  • encrypt, using your public key
  • sign, using the user's private key (you may need some way to identify the user here - passphrases, smart cards, biometrics, ...)
  • send to your server

On your server:

  • verify signature using the user's public key
  • decrypt using your private key
  • process as needed

Of course, this gets you into the complicated and wonderful world that is Public Key Infrastructure; but done correctly, you'll have a rather good assurance that the events actually happened the way your logs show.

绮烟 2024-09-15 00:17:50

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

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

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

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

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

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

I'm pasting in one of your comments here, because it goes to the heart of the matter:

Hi Eric. I should have pointed out
that the tool isn't going out
publically, it will go to a select
list of trusted users. The tool being
disassembled isn't an issue. I'm not
really bothered about encryption, all
I need to do is be able to verify that
they ran a specific process and got a
legitimate result. The tool verifies
stuff, so I don't want them to just
assume that something works fine and
not run the tool.

So basically, the threat we're protecting against is lazy users, who will fail to run the process and simply say "Yes Andy, I ran it!". This isn't too hard to solve, because it means we don't need a cryptographically unbreakable system (which is lucky, because that isn't possible in this case, anyway!) - all we need is a system where breaking it is more effort for the user than just following the rules and running the process.

The easiest way to do this is to take a couple of items that aren't constant and are easy for you to verify, and hash them. For example, your response message could be:

  • System Date / Time
  • Hostname
  • Username
  • Test Result
  • HASH(System Date / Time | Hostname | Username | Test Result)

Again, this isn't cryptographically secure - anyone who knows the algorithm can fake the answer - but as long as doing so is more trouble than actually running the process, you should be fine. The inclusion of the system date/time protects against a naive replay attack (just sending the same answer as last time), which should be enough.

赤濁 2024-09-15 00:17:50

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

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

YES-3456234
b23603f87c54800bef63746c34aa9195

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

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

如果用户的技术水平不足以弄清楚如何生成 md5 哈希值,那么这应该足够了。

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

现在你

YES-3456234
01428dd9267d485e8f5440ab5d6b75bd

可以验证

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

这意味着即使用户足够聪明来生成自己的 md5 哈希值,如果不知道秘密盐,他就无法伪造输出。

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

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

How about you take the output of your program (either "yes" or "no"?), and concatenate it with a random number, then include the hash of that string?

So you end up with the user sending you something like:

YES-3456234
b23603f87c54800bef63746c34aa9195

This means there will be plenty of unique hashes, despite only two possible outputs.

Then you can verify that md5("YES-3456234") == "b23603f87c54800bef63746c34aa9195".

If the user is not technical enough to figure out how to generate an md5 hash, this should be enough.

A slightly better solution would be concatenate another (hard-coded, "secret") salt in order to generate the hash, but leave this salt out of the output.

Now you have:

YES-3456234
01428dd9267d485e8f5440ab5d6b75bd

And you can verify that

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

This means that even if the user is clever enough to generate his own md5 hash, he can't fake the output without knowing the secret salt as well.

Of course, if he is clever enough, he can extract the salt from your program.

If something more bullet-proof is needed, then you're looking at proper cryptographic signature generation, and I'll just refer you to Piskvor's answer, since I have nothing useful to add to that :)

一生独一 2024-09-15 00:17:50

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

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

实际上这几乎是不可能的,因为你无法向用户隐藏盐。这基本上与这个问题中讨论的问题相同: How do you hide代码中的密钥?

In theory this is possible by using some sort of private salt and a hashing algorithm, basically a digital signature. The program has a private salt that it adds to the input before hashing. Private means the user does not have access to it, you however do know the salt.

The user sends you his result and the signature generated by the program. So you can now confirm the result by checking if hash(result + private_salt) == signature. If it is not, the result is forged.

In practice this is almost impossible, because you cannot hide the salt from the user. It's basically the same problem that is discussed in this question: How do you hide secret keys in code?

菊凝晚露 2024-09-15 00:17:50

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

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

You could make the application a web app to which they have no source code access or access to the server on which it runs. Then your application can log its activity, and you can trust those logs.

Once a user has an executable program in their hands, then anything can be faked.

亢潮 2024-09-15 00:17:50

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

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

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

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

It's worth noting that you aren't really looking for encryption.

The "non-repudiation" answer is almost on the money, but all you really need to guarantee where your message has come from is to securely sign the message. It doesn't matter if someone can intercept and read your message, as long as they can't tamper with it without you knowing.

I've implemented something similar before information was sent plaintext - because it wasn't confidential - but an obfuscated signing mechanism meant that we could be (reasonably) confident that the message was generated by our client software.

Note that you can basically never guarantee security if the app is on someone else's hardware - but security is never about "certainty", it's about "confidence" - are you confident enough for your business needs that the message hasn't been tampered with?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文