如何实现个人档案的密码保护? [英] How to implement password protection for individual files?

查看:156
本文介绍了如何实现个人档案的密码保护?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有一个策略这似乎是可行的,似乎是基于我所知道的逻辑(这可能只是危险的),但我不知道它是否真的是一个好的设计。所以告诉我:这是疯狂吗?有没有更好的/最好的方法?




  • 步骤1:用户输入纯文本密码,例如MyDifficultPassword

  • 步骤2:应用程序哈希用户密码,并使用该值作为对称密钥加密/解密数据文件。例如MyDifficultPassword - >HashedUserPwdAndKey。

  • 步骤3:应用程序从步骤2中删除散列值,并将新值保存在数据文件头(即数据文件的未加密部分)中,并使用该值验证用户的密码。例如HashedUserPwdAndKey - >HashedValueForAuthentication



基本上我是从通用的方式外推实现网站密码(当你'不使用OpenID,就是这样),它将用户密码的(盐化)哈希存储在数据库中,而不会保存实际的密码。但是,由于我使用散列用户密码进行对称加密密钥,因此我无法使用相同的值进行身份验证。所以我再次哈希,基本上就像另一个密码一样处理它,并将双重散列值保存在数据文件中。这样,我可以将文件存档到另一台电脑,只需输入密码即可解密。



所以这个设计是合理的安全的,还是绝望的天真, ?谢谢!



编辑:澄清和跟进问题:盐。

我以为盐必须保密才能有用,但是你的答案和链接意味着不是这样的。例如,由erickson链接的此规格(如下)说:


因此,这里定义的基于密码的密钥导出是密码,盐和迭代计数的函数,其中后两个数量不需要保密。


这是否意味着我可以将盐值存储在相同的位置/文件中哈希的关键还是比安全的更安全吗这是如何工作的?



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

解决方案

密钥生成



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



文件格式



您还可以考虑使用加密消息语法作为文件的格式。这将需要您的一些研究,但再次有现有的库可以使用,并开放了与其他软件(如支持S / MIME的邮件客户端)更为顺畅地进行互操作的可能性。



密码验证



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



或者,您可以计算内容上的MAC。对密码的哈希冲突更有可能对攻击者有用;内容上的哈希冲突可能是毫无价值的。但是,这样做可以让合法的收件人知道使用错误的密码进行解密。



加密盐



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



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



但是,假设他的下一个目标已经将他们的密码丢弃了。即使攻击者知道盐是什么,他的预先计算的表是毫无价值的,这个盐会改变每个密码产生的哈希值。他必须重新排列列表中的所有密码,将目标的盐粘贴到输入。每个不同的盐需要一个不同的字典,如果使用足够的盐,攻击者将不会有空间为他们存储字典。交易空间节省时间不再是一个选择;攻击者必须回避在他的列表中为他想要攻击的每个目标的每个密码哈希。



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


I'm writing a little desktop app that should be able to encrypt a data file and protect it with a password (i.e. one must enter the correct password to decrypt). I want the encrypted data file to be self-contained and portable, so the authentication has to be embedded in the file (or so I assume).

I have a strategy that appears workable and seems logical based on what I know (which is probably just enough to be dangerous), but I have no idea if it's actually a good design or not. So tell me: is this crazy? Is there a better/best way to do it?

  • Step 1: User enters plain-text password, e.g. "MyDifficultPassword"
  • Step 2: App hashes the user-password and uses that value as the symmetric key to encrypt/decrypt the data file. e.g. "MyDifficultPassword" --> "HashedUserPwdAndKey".
  • Step 3: App hashes the hashed value from step 2 and saves the new value in the data file header (i.e. the unencrypted part of the data file) and uses that value to validate the user's password. e.g. "HashedUserPwdAndKey" --> "HashedValueForAuthentication"

Basically I'm extrapolating from the common way to implement web-site passwords (when you're not using OpenID, that is), which is to store the (salted) hash of the user's password in your DB and never save the actual password. But since I use the hashed user password for the symmetric encryption key, I can't use the same value for authentication. So I hash it again, basically treating it just like another password, and save the doubly-hashed value in the data file. That way, I can take the file to another PC and decrypt it by simply entering my password.

So is this design reasonably secure, or hopelessly naive, or somewhere in between? Thanks!

EDIT: clarification and follow-up question re: Salt.
I thought the salt had to be kept secret to be useful, but your answers and links imply this is not the case. For example, this spec linked by erickson (below) says:

Thus, password-based key derivation as defined here is a function of a password, a salt, and an iteration count, where the latter two quantities need not be kept secret.

Does this mean that I could store the salt value in the same place/file as the hashed key and still be more secure than if I used no salt at all when hashing? How does that work?

A little more context: the encrypted file isn't meant to be shared with or decrypted by others, it's really single-user data. But I'd like to deploy it in a shared environment on computers I don't fully control (e.g. at work) and be able to migrate/move the data by simply copying the file (so I can use it at home, on different workstations, etc.).

解决方案

Key Generation

I would recommend using a recognized algorithm such as PBKDF2 defined in PKCS #5 version 2.0 to generate a key from your password. It's similar to the algorithm you outline, but is capable of generating longer symmetric keys for use with AES. You should be able to find an open-source library that implements PBE key generators for different algorithms.

File Format

You might also consider using the Cryptographic Message Syntax as a format for your file. This will require some study on your part, but again there are existing libraries to use, and it opens up the possibility of inter-operating more smoothly with other software, like S/MIME-enabled mail clients.

Password Validation

Regarding your desire to store a hash of the password, if you use PBKDF2 to generate the key, you could use a standard password hashing algorithm (big salt, a thousand rounds of hashing) for that, and get different values.

Alternatively, you could compute a MAC on the content. A hash collision on a password is more likely to be useful to an attacker; a hash collision on the content is likely to be worthless. But it would serve to let a legitimate recipient know that the wrong password was used for decryption.

Cryptographic Salt

Salt helps to thwart pre-computed dictionary attacks.

Suppose an attacker has a list of likely passwords. He can hash each and compare it to the hash of his victim's password, and see if it matches. If the list is large, this could take a long time. He doesn't want spend that much time on his next target, so he records the result in a "dictionary" where a hash points to its corresponding input. If the list of passwords is very, very long, he can use techniques like a Rainbow Table to save some space.

However, suppose his next target salted their password. Even if the attacker knows what the salt is, his precomputed table is worthless—the salt changes the hash resulting from each password. He has to re-hash all of the passwords in his list, affixing the target's salt to the input. Every different salt requires a different dictionary, and if enough salts are used, the attacker won't have room to store dictionaries for them all. Trading space to save time is no longer an option; the attacker must fall back to hashing each password in his list for each target he wants to attack.

So, it's not necessary to keep the salt secret. Ensuring that the attacker doesn't have a pre-computed dictionary corresponding to that particular salt is sufficient.

这篇关于如何实现个人档案的密码保护?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆