我正在使用用户+密码创建一个软件。在识别之后,用户可以访问一些半公共服务,但也加密一些只有用户可以访问的文件。
如果可能,用户必须按原样存储,无需修改。在auth之后,只要软件正在运行,用户和密码就会保存在内存中(我不知道是否可以)。
问题是如何将此用户+密码组合存储在可能不安全的数据库中?
我真的不明白我应该揭露什么。
假设我创建了一个这样的增强键:
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,但它并不重要,一般的例子就好了。 我已经阅读了一些类似的问题,但它们并不是很明确。
非常感谢你!
答案 0 :(得分:10)
加密很难做对,你提出问题是件好事。
存储密码:应使用键拉伸算法对密码进行哈希处理。通常,您希望使用库而不是自己实现它。密钥拉伸算法旨在咀嚼处理器周期,因此用漂亮的C代码评估它们是很好的。如果您使用glibc
的Linux系统,则可以使用crypt.crypt
模块(阅读man crypt
):
import crypt
encrypted = crypt.crypt(password, '$6$' + salt + '$')
这将返回一个ASCII字符串,您可以安全地将其存储在数据库中。 ($6$
是一个glibc扩展,它使用基于SHA-512的键拉伸功能。如果你没有这个扩展名,那么不要使用crypt.crypt
)。 (编辑:该算法与您在问题中提到的算法非常相似。但是,最佳做法通常是让图书馆执行这些操作而不是自己编写。)
加密文件:请勿自行执行此操作。安装GnuPG(或scrypt,bcrypt,ncrypt,你有什么)。当您设计自己的加密文件方式时,有一些事情很容易出错。这些工具使用正确的密钥派生函数,身份验证哈希和密码模式,无需任何其他配置。它们不是Python库,而是可执行文件,因此您必须编写一个使用subprocess
模块的包装器。
内存中的密码:不要。根据密码数据库检查用户密码后,使用密钥派生函数将密码转换为密钥。然后,您可以使用密钥解锁加密文件,但您无法再使用它来获取原始密码。
答案 1 :(得分:2)
如果您为每个用户使用不同的盐,则必须将其存储在某个位置(理想情况下位于不同的位置)。如果您为每个用户使用相同的salt,则可以在应用程序中对其进行硬编码,但可以认为它不太安全。 如果你不保留盐,你将无法将给定的密码与数据库中的密码相匹配。
盐的目的是使暴力或词典攻击更加困难。这就是为什么单独存储会更安全,以避免某人同时拥有哈希密码和相应的盐。