Encryption 如何为单个文件实施密码保护?

Encryption 如何为单个文件实施密码保护?,encryption,cryptography,passwords,Encryption,Cryptography,Passwords,我正在编写一个小型桌面应用程序,它应该能够加密数据文件并使用密码保护它(即,必须输入正确的密码才能解密)。我希望加密的数据文件是自包含和可移植的,因此身份验证必须嵌入到文件中(或者我假设是这样) 我有一个看起来可行的策略,并且根据我所知道的(这可能只是足够危险的)看起来是合乎逻辑的,但是我不知道它是否真的是一个好的设计。告诉我:这疯了吗?有更好/最好的方法吗 步骤1:用户输入纯文本密码,例如“MyDifficultPassword” 步骤2:应用程序散列用户密码,并使用该值作为对称密钥加密/解

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

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

  • 步骤1:用户输入纯文本密码,例如“MyDifficultPassword”
  • 步骤2:应用程序散列用户密码,并使用该值作为对称密钥加密/解密数据文件。e、 g.“我的困难密码”->“HashedUserPwdAndKey”
  • 第3步:应用程序对第2步中的散列值进行散列,并将新值保存在数据文件头(即数据文件的未加密部分)中,并使用该值验证用户的密码。e、 g.“HashedUserPwdAndKey”-->“HashedValueForAuthentication”
基本上,我是从实现网站密码的常用方法(即,当您不使用OpenID时)推断出来的,即在数据库中存储用户密码的(salt)散列,而从不保存实际密码。但是,由于我使用散列用户密码作为对称加密密钥,因此无法使用相同的值进行身份验证。所以我再次对它进行散列,基本上就像对待另一个密码一样,并将双散列值保存在数据文件中。这样,我就可以把文件拿到另一台电脑上,只需输入密码就可以解密

那么这个设计是合理的安全,还是无可救药的幼稚,还是介于两者之间呢?谢谢

编辑:澄清和后续问题回复:Salt。
我认为盐必须保密才能有用,但你的答案和链接暗示情况并非如此。例如,erickson的链接(如下)说:

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

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


更详细一点:加密的文件并不意味着要与其他人共享或解密,它实际上是单用户数据。但我希望将其部署在我无法完全控制的计算机(如工作中)的共享环境中,并能够通过简单地复制文件来迁移/移动数据(以便我可以在家里、不同的工作站等上使用它)。

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

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

正如Niyaz所说,如果您使用高质量的强算法实现(如and)进行散列和加密,这种方法听起来是合理的。此外,我还建议使用一个函数来减少创建包含所有密码哈希的字典的可能性

当然,reading也从来没有错。

密钥生成 我建议使用中定义的可识别算法(如PBKDF2)从密码生成密钥。它与您概述的算法类似,但能够生成更长的对称密钥以用于AES。您应该能够找到一个开源库,为不同的算法实现PBE密钥生成器

文件格式

您也可以考虑使用As格式作为文件。这需要您进行一些研究,但仍然有现有的库可供使用,这为与其他软件(如支持S/MIME的邮件客户端)更顺畅地交互提供了可能性

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

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

加密盐 有助于阻止预先计算的字典攻击

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

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


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

是否确实需要将哈希密码保存到文件中。你不能把密码(或散列密码)和一些密码一起使用吗