我正在编写一个 Rails 3 Web 应用程序,匿名用户将能够在其中输入有关事件的详细信息,并将它们加密到我的数据库中,只能由该用户或具有用户在创建它时决定的每个事件密码的任何人检索.
我做这一切是为了让我的头脑了解加密和散列编程,所以这可能有点矫枉过正,但我想要一个“最安全”做事方式的工作模型,无需进入双重身份验证或未连接到隐藏在地壳下 30 公里的秘密保险库中的任何网络的计算机(我已经有两个)。
我正在存储的当前数据及其全部加密如下,我只是想要一些关于我是否使用任何不安全的方法或任何会削弱我的应用程序(尤其是我的用户数据)攻击的反馈.
每个事件都使用透明数据加密将以下字段存储在 Oracle 数据库中:
- ID
- 事件数据
- 密码哈希
- 加密_iv
- 加密密钥
- admin_retrievable_event_data
- admin_encrypted_iv
- admin_encrypted_key
网络服务器以受限制的系统权限运行,已完全修补,并且网络服务器进程无法浏览站点目录结构之外的内容。网络服务器仅运行 HTTPS。
当用户创建事件时,他们提供明文数据进入 event_data 字段,并提供密码来保护该数据。要检索数据,他们只需输入提交表格后提供的 ID 号以及他们选择的密码。在事件创建期间,用户还可以选中一个框以允许生成管理员可检索的数据(如果他们选择的话)。此选项默认设置为 false。
出于管理员检索的目的,该事件的明文仍保存在内存中,如下所述。
使用 AES256 CBC 加密以及安全生成的随机 IV 和密钥来保护事件数据。然后使用存储在服务器上的公钥(RSA 2048 位)对 IV 和密钥进行加密。然后,IV 和密钥都与用户提供的密码的 SHA-256 散列进行异或,随后都存储在数据库中。
然后使用 SHA-256 对用户密码进行哈希处理,使用 256 位安全随机生成的令牌作为盐,使用包含哈希和盐的冒号分隔符创建一个字符串,然后使用公钥加密(与之前的相同) ) 并存储在数据库 password_hash 字段中。
然后,明文事件数据使用新随机生成的密钥和 IV 进行相同的过程以供管理员检索并存储,然后使用不同的公钥(仅用于管理员检索)对密钥和 IV 进行加密,并存储在数据库而不是对任何东西进行异或。
要检索数据,用户输入他们的事件 ID 和密码。首先,password_hash 使用私钥(存储在服务器上的非 Web 可访问目录中)解密(该私钥的密码被硬编码到应用程序中),然后使用用户输入的密码重新散列从现在未加密的数据库条目中提取盐,如果它与存储的加盐密码的哈希匹配,则该过程继续(否则,返回“未找到事件 ID 或密码不正确”的错误)。
然后将加密的密钥和 IV 与新生成的用户密码的未加盐散列进行异或运算,并使用用于密码散列的相同私钥/密码进行解密。这些随后用于解密 event_data,并将数据返回给用户。
如果管理员希望检索数据,他们必须上传私钥并输入私钥密码,此时管理员 IV 和密钥被解密,内存中的私钥被销毁,管理员可检索事件数据被解密.
所以,这就是我对这个东西的设计,我发现的唯一当前弱点是将用于事件和用户密码加密的私钥存储在服务器上,并将该私钥密码硬编码到应用程序中。但是,如果不在基于硬件的加密设备上花费大量资金,我就看不到解决方法。如果有人可以建议一种更好的架构方法来避免该问题,并且不会给最终用户带来不便,方法是为每个事件生成单独的证书并为他们提供私钥,随后迫使他们在每次想要解密事件时重新上传它数据,我对此持开放态度。
如果您发现除这些问题之外的任何问题,我也很想知道它,并且希望获得资源来阅读或解释问题是什么以及我可以做些什么来纠正它。
请注意,我不具备大学水平的数学知识,尽管我很想了解加密,但我远远低于我可以为自己进行任何类型的密码分析的水平。在这个项目中,我只是简单地阅读了我能理解的水平的概述,并尝试应用这些知识。