在哪里存储密码?

时间:2011-04-10 13:38:26

标签: android database passwords

我正在编写一个android密码管理器应用程序,我想在某处存储主密码,但我不知道在哪里。我应该使用我选择的硬编码密码加密用户提供给我的主密码,然后将其存储到数据库中吗?或者我应该做别的事吗?

2 个答案:

答案 0 :(得分:5)

永远不要存储未加密的密码。

对于密码,您无法安全加密(因为您必须在某处存储解密密钥),您应该只存储不可逆的哈希值。

这样,您可以在用户提供密码时将密码与哈希值进行比较。如果匹配,则可以使用给定密码解密存储的用户:密码对。

PS:不要忘记加密哈希和please do it properly

答案 1 :(得分:3)

不,不,一千次没有。

如果您被允许查看GPLv2代码,请查看KeePass源代码。

主密码变为密钥(基于密码的密钥派生),该密钥用于加密和解密各个数据(个人密码)。

因此,该过程与此类似: 1.关闭可以关闭的任何交换磁盘。询问用户主密码。

  1. 通过使用PBKDF2(HMAC-SHA-256,主密码,存储的随机盐*,2000000,256)之类的东西,将主密码转换为仅内存主加密密钥 - PBKDF2也是已知的作为RFC2898和PKCS#5。 HMAC-SHA-256是散列函数。主密码是用户输入的内容 - 永远不会以任何形式保存!无论何时选择新的主密码,存储的随机盐都是新生成的64位或更大的加密随机值,并保存而不是保存任何形式的主密码。 2000000是我们要运行HMAC的次数,它存储并应该是用户可选择的 - 这应该是你可以等待的数量(KeePass有一个功能来对它们进行基准测试,看看有多少需要1秒 - 我建议将其增加到4或5秒)。 256是所需输出的位数 - 在这种情况下,我假设您将使用CAMELLIA-256或AES-256来加密您的密码(只需匹配您的加密函数用于密钥的位数) 。 是的,可以使用scrypt或bcrypt。

  2. 检查主密码是否正确:如果我们要使用现有主密码进入现有数据库,请使用仅内存中密钥解密某些固定数据,例如“默认”密码。如果value解密为您期望的值,则输入的主密码是正确的,否则,主密码错误和/或数据库损坏。如果我们正在启动新数据库或更改主密码,请加密该“默认”密码并存储加密值。

  3. 使用主加密密钥解密URL,用户名,备注和其他非密码数据。

  4. 使用主加密密钥仅根据用户的请求解密现有密码(但只有用户请求的精确密码),然后在完成数据或定时器后立即用随机垃圾覆盖数据用尽。使用所述主加密密钥加密新密码。

  5. 一旦用户完成或计时器用完,用随机垃圾覆盖所有变量(最特别是仅存储器内的主加密密钥)。

  6. 注意你正在存储:

    • 迭代次数
    • 加密的“固定”密码,仅用于验证主密码是否正确
    • 加密的用户名,网址,备注等
    • 加密的个人网站密码

    您永远不会存储主密码或其哈希值。您永远不会将主密码,其哈希值,甚至生成的主加密密钥与其他任何内容进行比较。您只需获取主密码并将其转换为主加密密钥,然后使用该密钥加密或解密数据 - 已知数据(“固定”密码)可让您查看该密钥是否给出了预期结果。当您知道主密码正确时,未知数据(用户输入和关注的所有内容)也会被加密或解密。