维护消息完整性

时间:2009-04-02 17:40:20

标签: asp.net-mvc language-agnostic hash digital-signature

我有一条消息说我要传递给自己,这将受到中间人攻击。因此,我担心在发送消息之前保持消息的完整性以及我收到消息的时间。

应该假设,一旦我将消息发送给自己,将来我将无法获得有关所发送消息的信息。该消息是完全独立的。

为此,我知道应该在发送消息之前散列消息内容并比较散列,并且在发送消息之后,如果它们不同,则消息已被篡改。

当然,如果中间人知道哈希实际上只是消息内容的哈希值,那么因为消息是自包含的,他只能创建新内容并应用与内容相同的哈希算法。

问题是,在生成哈希时,我应该在多长时间内随机化消息内容?什么时候到达收益递减点?

在这种情况下,我有一组键/值对。为此,我知道我必须采取的步骤是:

  1. 在邮件中添加salt。盐是世界其他地方的秘密。它在散列之前附加到消息的内容。
  2. 在生成哈希值之前以一致的方式对键/值对进行排序。
  3. 虽然不是直接相关,但是在散列之前会将时间戳添加到每封邮件的内容中,以防止重放攻击。
  4. 这些是我正在考虑的可选步骤:

    1. 在我订购之前转换密钥。我考虑过逆转它们,然后按计数/键排序。
    2. 使用分隔键/值对的分隔符(包括键/值的分隔符和对的分隔符)。
    3. 注意

      邮件隐私这里的要求,所以我不是在寻找加密。值必须以纯文本格式传输。

      最后,我应该避免哪些哈希算法?


      具体细节信息

      我有一个ASP.NET MVC站点,我有一个处理输入验证和持久性的控制器。

      如果(基于启发式,并不重要)输入被确定为自动垃圾邮件尝试,则使用输入值创建IDictionary<string, string>模型,并将ViewResult发送到常规CAPTCHA页面

      在该视图中,在包含CAPTCHA控件的表单中,IDictionary<string, string>的内容将写入隐藏的输入字段,表单的操作将与内容最初的操作相同张贴到。这样,MVC可以在重新提交表单时获取值。

      正因为如此,我无法加密键/值对(或者我可以而且应该,告诉我原因和方法!)。

      当然,我需要再添加一个值,其中包含散列消息内容。如果该值存在,那么控制器将检查是否保持了消息完整性,并允许输入持久存在。

      解决方案

      我选择使用System.Security.Cyrptography.Pkcs命名空间中的SignedCms类,该命名空间代表CMS / PKCS#7消息的链接和验证。

      详细说明,我已经使用MAKECERT.EXE创建了一个自行颁发的证书,然后在我的代码中,我使用此处的示例对数据进行数字签名:

      http://blogs.msdn.com/shawnfa/archive/2006/02/27/539990.aspx

      现在,应该保持导出的私钥上的密码安全,以及服务器上的安全性,这使得它更少编程。

      我必须为重放攻击的时间戳添加一个额外的密钥,但这不会太难。

      答案是Kalium,而不是他的initial post,但是他的后续评论指出了数字签名的方式,最终我发现了如何在.NET中使用它们。 / p>

      感谢所有贡献的人。

5 个答案:

答案 0 :(得分:6)

我认为PGP / GPG就是你想要的。

答案 1 :(得分:2)

允许应用程序验证其自身消息未被篡改的最直接方法是使用密钥散列消息身份验证代码。消息以明文形式发送,但它还包含一个哈希以防止篡改。散列取决于消息内容和密钥。在不知道密钥的情况下,中间的人不能在更改的消息上伪造哈希。由于您的应用程序都会创建和验证消息,因此永远不需要泄露密钥。

我特别推荐RFC-2104 http://www.ietf.org/rfc/rfc2104.txt中描述的实现,因为它已经过仔细考虑,以避免大多数可能的陷阱。

如果不信任方也必须验证消息的真实性,那么您应该使用数字签名方案。

.Net库中可能有一些支持。 Miles帮助提供(作为注释)MSDN网页的链接,用于使用SHA1哈希实现密钥HMAC的.Net库函数:http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx

答案 2 :(得分:1)

你想要一个Digitally Signed message。使用GPG,您可以在不使用加密的情况下对消息进行签名。但是没有人能够篡改它,因为他们无法生成哈希 - 只有你可以,因为哈希使用你的私钥

答案 3 :(得分:0)

您应该对消息进行数字签名(因此Kalium推荐的PGP / GPG作为选项相关)。您可以创建的任何纯哈希都可以由攻击者重新创建。数字签名 - 使用您的私人签名密钥,以便您的公钥可用于验证它 - 是解决方案。任何其他事情都是徒劳的。

答案 4 :(得分:0)

假设您无法通过“安全”通道(即哈希)传递任何信息,请按以下步骤操作:

  1. 散列消息,然后使用私钥对散列进行签名。在邮件中包含签名的哈希。
  2. 当您收到消息时,使用公钥解密签名的哈希并验证它是否与消息的实际哈希值匹配。
  3. 攻击者无法“伪造”某条消息,因为他们需要拥有您的私钥才能加密新的哈希值。

    正如其他人所说,这只是简单的香草数字签名,可以像PGP / GPG那样处理