我正在开发一个需要存储和使用机密的软件。
例如,这些秘密可以是:
- 连接数据库的密码
- OAuth 2.0
client_credentials
授权的客户端密码。
我需要将这些密码存储在某个地方(最好是在某种配置文件中)并以合理的安全性保护它们。
合理的安全性意味着:没有基于重型硬件的解决方案,例如 HSM 或复杂的基础设施(PKI,...)。
该软件采用 Java 编写,它应该运行在 Java 可以运行的任何地方(尤其是 Windows、GNU/Linux、Solaris、AIX)。
它不能依赖操作系统或特定于发行版的工具,例如 GNOME 密钥库、KDE 钱包或任何这些工具,除非 Java 提供了处理它们的方法(但我对此表示怀疑)。
我想在配置软件时使用对称密码术来加密秘密,并在需要时在运行时解密它们。但我不知道如何处理加密密钥。
我找到了 4 个可能的解决方案:
- 使用PBKDF2 (SHA256-AES256-CBC) 或普通AES256-CBC与硬编码的加密密钥和可选的一些代码混淆(使用ProGuard)
- 有一个专门的 CWE:CWE-321 - Use of Hard-coded Cryptographic Key。所以我怀疑这是解决方案。
- 将PBKDF2 (SHA256-AES256-CBC) 或普通AES256-CBC与文件系统上文件中的密钥一起使用
- 它在文件中公开了应该通过某种方式保护的密钥
- 加密文件系统和/或
- 强制 ACL
- 还要别的吗?
- 它在文件中公开了应该通过某种方式保护的密钥
- 使用 Java 密钥库
- Java keystore需要密码才能解锁,那么Java keystore密码存放在哪里呢?如何保护它?蛇正在吃自己的尾巴……
- 不知何故相当于2
- 使用白盒密码学
- 它已经显示出一些弱点,或多或少等同于混淆。(在选项 1 中)。
- 我不确定 WBC 的 Java 实现是否成熟。
我见过这个问题:在 Web 应用程序中存储用户名/密码的做法。
所以我的问题是:保护我的秘密数据的“最佳”合理选择是什么?
我觉得2更好,毕竟它很简单,而且密钥保护将依赖于操作系统而不是软件本身,就像OpenSSH一样,但我并不完全相信。
编辑:
PBKDF2 可以替换为任何其他密码基密钥派生算法,例如 PKCS #12 v1 密钥派生算法。
奖金:
如果我要在PBKDF2 (SHA256-AES256-CBC) 或普通AES256-CBC之间进行选择,什么是最好的?
- 据说 PBKDF2 可以很好地保护密码,因为它“慢”。它就是为此而设计的。
- AES256-CBC 更简单(无需像 PBKDF2 中那样对密钥进行加盐/散列/迭代密钥)