我正在开发一个跨平台(JS/iOS/Android)列表管理器应用程序,它通过 REST API 保存数据,我想确保在客户端正确加密任何文本数据,这样就无法解密数据服务器端,并且在数据库被盗的不幸情况下,不值得花任何精力尝试解密它。
经过数月的研究和反复试验,我决定 CBC 操作模式下的 AES 加密是最佳选择,因为它的强度和在所有平台上的广泛采用。我决定基于 OpenSSL 的类似算法进行密钥派生,以便我有一个可靠的命令行工具来测试我的实现的准确性。
剩下的唯一事情就是以某种方式确保用户提供的加密密码短语的有效性,它永远不会直接到达服务器端。到目前为止,我想到的最好的想法是在登录后解密几个列表项,以测试它们是否可以通过对密文应用 HMAC 散列来正确解密,而这又需要在服务器端存储 HMAC 散列。
我有一些问题:
- 有没有其他方法可以安全地确保成功登录后提供的密码的有效性?
- 在 AES CBC 加密中重复使用相同的密码作为相同加密数据的 HMAC 散列中的密钥是否安全?
我见过这个 TLS 线程,但我不需要典型的客户端/服务器设置之间的加密。在我的情况下,客户端加密数据,存储在云中,下次同一个客户端或另一个客户端将解密它。因此,TLS 中的握手等对我来说没有多大意义。
注意 1:我故意将其称为上面的“密码短语”,以强调它与在登录时验证并作为哈希存储在用户帐户中的用户密码不同。
注意 2:最重要的是,请求将通过 HTTPS 传输。上述重点不是确保传输安全,而是将数据的可读性限制在客户端以获得众多安全优势。
我很感激任何反馈。谢谢!