【发布时间】:2011-08-02 11:55:08
【问题描述】:
我正在编写一个 android 密码管理器应用程序,我想将主密码存储在某个地方,但我不知道在哪里。我是否应该使用我选择的硬编码密码加密用户给我的主密码,然后将其存储到数据库中?还是我应该做点别的?
【问题讨论】:
-
不存储主密码的密码管理器的整个想法不是吗?您将单个密码与主密码一起存储为加密密钥。并且永远不会存储主密码。
标签: android database passwords
我正在编写一个 android 密码管理器应用程序,我想将主密码存储在某个地方,但我不知道在哪里。我是否应该使用我选择的硬编码密码加密用户给我的主密码,然后将其存储到数据库中?还是我应该做点别的?
【问题讨论】:
标签: android database passwords
您不应该存储未加密的密码。
对于您无法安全加密的密码(因为您必须将解密密钥存储在某处),您应该只存储它的不可逆哈希。
这样,当用户给你密码时,你可以将密码与哈希值进行比较。如果匹配,您可以使用给定密码解密存储的 user:password 对。
PS:别忘了给哈希加盐和please do it properly。
【讨论】:
不,不,一千倍不。
如果允许您查看 GPLv2 代码,请查看 KeePass 源代码。
主密码转换为密钥(基于密码的密钥派生),该密钥用于加密和解密各个数据片段(单个密码)。
因此,过程类似这样: 1. 关闭任何可以关闭的交换到磁盘。询问用户主密码。
通过使用类似 PBKDF2(HMAC-SHA-256, master password, stored random salt*, 2000000, 256) 之类的东西,将主密码转换为仅内存中的主加密密钥 - PBKDF2 也是已知的作为 RFC2898 和 PKCS #5。 HMAC-SHA-256 是散列函数。主密码是用户输入的任何内容 - 这根本不会以任何形式保存! Stored random salt is a 64-bit or larger cryptographically random value generated fresh whenever a new master password is selected, and saved instead of saving any form of the master password whatsoever. 2000000 是我们要运行 HMAC 的次数,它被存储并且应该是用户可选择的 - 这应该是您可以等待的尽可能多的次数(KeePass 具有对它们进行基准测试并查看多少需要 1 秒- 我建议将其增加到 4 或 5 秒)。 256 是所需的输出位数 - 在这种情况下,我假设您将使用 CAMELLIA-256 或 AES-256 来加密您的密码(只需匹配您的加密功能用于密钥的位数) . 是的,可以使用 scrypt 或 bcrypt。
检查主密码是否正确:如果我们要使用现有主密码进入现有数据库,请使用该内存中的密钥来解密一些固定数据,例如“默认”密码。如果值解密为您期望的值,则输入的主密码正确,否则,主密码错误和/或数据库已损坏。如果我们要启动新数据库或更改主密码,请加密“默认”密码并存储加密值。
使用主加密密钥解密 URL、用户名、注释和其他非密码数据。
仅根据用户的请求使用主加密密钥解密现有密码(但仅限用户请求的精确密码),然后在完成后立即用随机垃圾或计时器覆盖数据用尽。使用所述主加密密钥加密新密码。
一旦用户完成操作或计时器用完,就用随机垃圾覆盖所有变量(尤其是内存中的主加密密钥)。
注意你正在存储:
您永远不会存储主密码或其哈希值。您永远不会将主密码、它的哈希,甚至生成的主加密密钥与其他任何东西进行比较。您只需要获取主密码并将其转换为主加密密钥,然后使用该密钥加密或解密数据 - 已知数据(“固定”密码)可让您查看该密钥是否给出了预期的结果。当您知道主密码正确时,未知数据(用户输入和关心的所有内容)也会被加密或解密。
【讨论】: