21

我正在编写一个小桌面应用程序,它应该能够加密数据文件并用密码保护它(即必须输入正确的密码才能解密)。我希望加密的数据文件是独立且可移植的,因此必须将身份验证嵌入文件中(或者我假设)。

根据我所知道的,我有一个看起来可行且合乎逻辑的策略(这可能足以造成危险),但我不知道它是否真的是一个好的设计。所以告诉我:这疯了吗?有没有更好/最好的方法来做到这一点?

  • 第一步:用户输入明文密码,例如“MyDifficultPassword”
  • 第 2 步:应用程序对用户密码进行哈希处理,并使用该值作为对称密钥来加密/解密数据文件。例如“MyDifficultPassword”-->“HashedUserPwdAndKey”。
  • 第 3 步:应用程序对第​​ 2 步中的哈希值进行哈希处理,并将新值保存在数据文件头(即数据文件的未加密部分)中,并使用该值来验证用户的密码。例如 "HashedUserPwdAndKey" --> "HashedValueForAuthentication"

基本上,我是从实现网站密码的常用方法(即当您不使用 OpenID 时)推断出来的,即将用户密码的(加盐)哈希存储在您的数据库中,并且从不保存实际密码. 但是由于我使用散列用户密码作为对称加密密钥,所以我不能使用相同的值进行身份验证。所以我再次对其进行哈希处理,基本上将其视为另一个密码,并将双重哈希值保存在数据文件中。这样,我可以将文件带到另一台 PC 上,只需输入我的密码即可对其进行解密。

那么这种设计是相当安全的,还是天真无望的,还是介于两者之间?谢谢!

编辑:澄清和后续问题:盐。
我认为盐必须保密才能有用,但您的答案和链接暗示情况并非如此。例如,由埃里克森(下)链接的这个规范说:

因此,此处定义的基于密码的密钥派生是密码、盐和迭代计数的函数,其中后两个量不需要保密。

这是否意味着我可以将盐值存储在与散列密钥相同的位置/文件中,并且仍然比在散列时完全不使用盐更安全?这是如何运作的?

更多上下文:加密文件不打算与其他人共享或解密,它实际上是单用户数据。但是我想将它部署在我无法完全控制的计算机上的共享环境中(例如在工作中),并且能够通过简单地复制文件来迁移/移动数据(这样我就可以在家中使用不同的工作站等)。

4

5 回答 5

24

密钥生成

我建议使用公认的算法,例如在PKCS #5 2.0 版中定义的 PBKDF2从您的密码生成密钥。它类似于您概述的算法,但能够生成更长的对称密钥以用于 AES。您应该能够找到为不同算法实现 PBE 密钥生成器的开源库。

文件格式

您还可以考虑使用加密消息语法作为文件格式。这需要您进行一些研究,但同样有现有的库可供使用,并且它开辟了与其他软件更顺畅地互操作的可能性,例如启用 S/MIME 的邮件客户端。

密码验证

关于您存储密码哈希的愿望,如果您使用 PBKDF2 生成密钥,您可以为此使用标准密码哈希算法(大盐,一千轮哈希),并获得不同的值。

或者,您可以计算内容的 MAC。密码上的哈希冲突更有可能对攻击者有用;内容上的哈希冲突可能毫无价值。但它可以让合法的接收者知道错误的密码被用于解密。

密码盐

Salt有助于阻止预先计算的字典攻击。

假设攻击者有一个可能的密码列表。他可以对每个哈希值进行哈希处理,并将其与受害者密码的哈希值进行比较,看看是否匹配。如果列表很大,这可能需要很长时间。他不想在下一个目标上花费太多时间,所以他将结果记录在一个“字典”中,其中哈希指向其相应的输入。如果密码列表非常非常长,他可以使用彩虹表之类的技术来节省一些空间。

但是,假设他的下一个目标将他们的密码加盐。即使攻击者知道盐是什么,他的预计算表也毫无价值——盐会改变每个密码产生的哈希值。他必须重新散列他列表中的所有密码,将目标的盐添加到输入中。每种不同的盐都需要不同的字典,如果使用了足够多的盐,攻击者将没有空间为所有盐存储字典。交易空间以节省时间不再是一种选择;攻击者必须回退到对他想要攻击的每个目标的列表中的每个密码进行哈希处理。

所以,没有必要对盐保密。确保攻击者没有与该特定盐对应的预先计算的字典就足够了。

于 2008-09-11T06:37:40.467 回答
2

正如 Niyaz 所说,如果您使用强算法的高质量实现,例如SHA-265AES进行散列和加密,这种方法听起来很合理。此外,我建议使用Salt来减少创建所有密码哈希字典的可能性。

当然,阅读Bruce SchneierApplied Cryptography也永远不会出错。

于 2008-09-11T06:03:17.990 回答
1

如果您使用的是强哈希算法 (SHA-2) 和强加密算法 (AES),则可以使用这种方法。

于 2008-09-11T05:56:00.037 回答
1

为什么不使用支持密码保护文件的压缩库?我过去使用过包含 XML 内容的受密码保护的 zip 文件:}

于 2008-09-11T06:01:43.640 回答
0

是否真的需要将散列密码保存到文件中。您不能只使用带有一些盐的密码(或散列密码),然后用它加密文件。解密时只需尝试使用密码+盐解密文件。如果用户提供了错误的密码,则解密的文件不正确。

我能想到的唯一缺点是如果用户不小心输入了错误的密码并且解密速度很慢,他必须等待重试。当然,如果忘记密码,则无法解密文件。

于 2008-09-11T07:08:06.337 回答