将用户和密码存储在数据库中
我正在创建一个带有用户名+密码的软件。经过身份验证后,用户可以访问一些半公开的服务,但也可以加密一些只有该用户才能访问的文件。
如果可能的话,用户必须按原样存储,不得修改。身份验证后,只要软件运行,用户和密码就会保留在内存中(我也不知道这是否可以)。
问题是我应该如何将此用户+密码组合存储在可能不安全的数据库中?
我真的不明白我应该暴露什么。
假设我创建了一个这样的增强密钥:
salt = random 32 characters string (is it okay?) key = hash(usr password + salt) for 1 to 65000 do key = hash(key + usr password + salt)
我应该将 [明文用户]、[增强密钥] 和 [盐] 存储在数据库中吗?
另外,我应该使用什么来每次使用新密码加密(使用 AES 或 Blowfish)某些文件? 我应该生成一个新的盐并使用(存储在程序内存中的密码+盐)创建一个新的增强密钥吗? 在这种情况下,如果我将加密文件存储在数据库中,我可能应该只存储盐。 该数据库与我存储用户+密码组合的位置相同。
只有有人能够生成密钥但不知道密码时才能解密该文件。正确的 ?
我将 Python 与 PyCrypto 一起使用,但这并不重要,一个一般的例子就可以了。 我读过一些类似的问题,但它们都不是很明确。
非常非常感谢!
I am creating a software with user + password. After autentification, the user can access some semi public services, but also encrypt some files that only the user can access.
The user must be stored as is, without modification, if possible. After auth, the user and the password are kept in memory as long as the software is running (i don't know if that's okay either).
The question is how should i store this user + password combination in a potentially unsecure database?
I don't really understand what should i expose.
Let's say I create an enhanced key like this:
salt = random 32 characters string (is it okay?) key = hash(usr password + salt) for 1 to 65000 do key = hash(key + usr password + salt)
Should I store the [plaintext user], [the enhanced key] and [the salt] in the database ?
Also, what should I use to encrypt (with AES or Blowfish) some files using a new password everytime ?
Should I generate a new salt and create a new enhanced key using (the password stored in memory of the program + the salt) ?
And in this case, if i store the encrypted file in the database, i should probably only store the salt.
The database is the same as where i store the user + password combination.
The file can only be decrypted if someone can generate the key, but he doesn't know the password. Right ?
I use Python with PyCrypto, but it's not really important, a general example is just fine.
I have read a few similar questions, but they are not very explicit.
Thank you very very much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您为每个用户使用不同的盐,则必须将其存储在某个地方(最好是在不同的地方)。如果您为每个用户使用相同的盐,您可以在应用程序中对其进行硬编码,但可能会被认为不太安全。
如果您不保留盐,您将无法将给定的密码与数据库中的密码进行匹配。
加盐的目的是让暴力破解或字典攻击变得更加困难。这就是为什么单独存储会更安全,以避免有人同时拥有哈希密码和相应的盐。
If you use a different salt for each user, you must store it somewhere (ideally in a different place). If you use the same salt for every user, you can hardcode it in your app, but it can be considered less secure.
If you don't keep the salt, you will not be able to match a given password against the one in your database.
The aim of the salt is to make bruteforce or dictionnary attacks a lot harder. That is why it is more secure if store separately, to avoid someone having both hash passwords and corresponding salts.
加密货币很难正确,但提出问题是件好事。
存储密码:密码应使用密钥拉伸算法进行哈希处理。通常,您希望使用库而不是自己实现它。关键拉伸算法旨在消耗处理器周期,因此最好使用漂亮的 C 代码来评估它们。如果您使用的是
glibc
的 Linux 系统,则可以使用crypt.crypt
模块(请阅读man crypt
):这会返回一个 ASCII 字符串您可以安全地将其存储在数据库中。 (
$6$
是一个 glibc 扩展,它使用基于 SHA-512 的密钥拉伸函数。如果您没有此扩展,则不要使用crypt.crypt
)。 (编辑:该算法与您在问题中询问的算法非常相似。但是,最佳实践通常是让库来做这些事情,而不是自己动手。)加密文件:不要你自己做吧。安装 GnuPG(或者 scrypt、bcrypt、ncrypt,等等)。当您设计自己的文件加密方式时,有一些事情很容易出错。这些工具使用正确的密钥派生函数、身份验证哈希和密码模式,无需任何其他配置。它们不是 Python 库,而是可执行文件,因此您必须编写一个使用
subprocess
模块的包装器。内存中的密码:不要。根据密码数据库检查用户密码后,使用密钥派生函数将密码转换为密钥。然后,您可以使用该密钥来解锁加密的文件,但您无法再使用它来取回原始密码。
Crypto is hard to get right, it's good that you're asking questions.
Storing passwords: Passwords should be hashed using a key stretching algorithm. Typically, you want to use a library rather than implement it yourself. Key stretching algorithms are designed to chew up processor cycles, so it's nice to evaluate them with nice C code. If you are on a Linux system with
glibc
, you can use thecrypt.crypt
module (readman crypt
):This returns an ASCII string which you can safely store in your database. (The
$6$
is a glibc extension that uses a key stretching function based on SHA-512. If you don't have this extension, then don't usecrypt.crypt
). (Edit: The algorithm is very similar to the one you asked about in your question. However, best practice is usually to let a library do that stuff rather than rolling your own.)Encrypting files: Do not do this yourself. Install GnuPG (or scrypt, bcrypt, ncrypt, what have you). There are a few things that can easily go wrong when you design your own way to encrypt files. These tools use the proper key derivation functions, authentication hashes, and cipher modes without any additional configuration. They're not Python libraries, but executables, so you'll have to write a wrapper that uses the
subprocess
module.Passwords in memory: Don't. Once you've checked the user's password against your password database, convert the password to a key using a key derivation function. You can then use the key to unlock encrypted files, but you can no longer use it to get the original password back.