如何对单个文件实施密码保护? [英] How to implement password protection for individual files?

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

问题描述

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

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?

  • 第 1 步:用户输入纯文本密码,例如我的困难密码"
  • 第 2 步:应用对用户密码进行哈希处理,并使用该值作为对称密钥来加密/解密数据文件.例如MyDifficultPassword"--> HashedUserPwdAndKey".
  • 第 3 步:应用对第 2 步中的散列值进行哈希处理,并将新值保存在数据文件标头(即数据文件的未加密部分)中,并使用该值来验证用户的密码.例如"HashedUserPwdAndKey" --> "HashedValueForAuthentication"

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

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!

澄清和后续问题:盐.
我认为盐必须保密才能有用,但您的回答和链接暗示情况并非如此.例如,erickson 链接的本规范(如下)说:

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:

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

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.).

推荐答案

密钥生成

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

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.

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

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.

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

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.

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

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.

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

Salt helps to thwart pre-computed dictionary attacks.

假设攻击者有一个可能的密码列表.他可以对每个进行散列并将其与受害者密码的散列进行比较,看看是否匹配.如果列表很大,这可能需要很长时间.他不想在下一个目标上花费太多时间,因此他将结果记录在字典"中,其中散列指向其相应的输入.如果密码列表非常非常长,他可以使用Rainbow Table 以节省一些空间.

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天全站免登陆