Java / C++ 加密和 JNI 接口
Java / C++ Encryption and the JNI interface
场景
我们正在开发一个应用程序,它使用 Java 前端并在 C++ 端实现更复杂的数学算法。为此,有 Java native
函数通过 JNI 实现,通过 Java.
访问 C++ 功能
问题
从历史上看,我们遇到了越来越多的凭据在相对较大的代码库中飞来飞去的问题,几乎都是 Java 端,应用程序特定配置文件中的一些可配置凭据,后者可以忽略 w.r.t.本题范围.
我们想提高应用程序的安全性。我们面临的问题是我们的应用程序必须能够 运行 离线,因此无论我们使用什么私钥来解密我们的数据,它都将与应用程序一起交付。我们正在考虑我们的选择,但其中 none 似乎最不安全:
- 保留密码 Java 端并使用
crypto
包 - 尽管如此,加密算法仍然可以识别,用于加密的密码仍必须公开存储在某个地方,因此可以相对容易地解密.此外,JAR 相对容易访问。
- 保留密码 C++ 端并使用函数
decryptKey
通过传递密码,用私钥解密 C++ 端,然后将其原样返回。在这种情况下,JNI 成为漏洞,因为很容易想到只构建您自己的 JAR,包含我们的 DLL,然后访问本机 decryptKey
函数来检索纯文本密码。
- 将所有关键依赖逻辑转移到 C++。这毫无意义,因为我们必须将逻辑转移到不属于它的地方。此外,一些实现需要需要提供凭据的第 3 方 Java API,因此遗憾的是这不是一个选项。
问题
想必这在业界并不少见,那么最明智的处理方式是什么?目前,这些方法仅通过隐蔽性 安全性 引入,其有效性充其量是值得商榷的,最坏的情况下仅略高于零。行业内是否有处理此问题的标准程序?
首先,您的产品需要能够与能够保护您的私钥安全的产品集成。这些产品包括 TPM, HSM and KMS。这将证明对本地和基于云的生产环境非常有用。
其次,您应该实施 envelope encryption 机制,其中数据加密密钥使用将存储在 TPM/HSM/KMS 中的主密钥加密。加密后的数据加密密钥可以与数据一起存储。
第三,您应该实施 key rotation,每隔一段时间更换一次 master/data 密钥。
第四也是最后一点,您应该咨询 Information Security 而不是 Whosebug 以解决未来的强化问题。
场景
我们正在开发一个应用程序,它使用 Java 前端并在 C++ 端实现更复杂的数学算法。为此,有 Java native
函数通过 JNI 实现,通过 Java.
问题
从历史上看,我们遇到了越来越多的凭据在相对较大的代码库中飞来飞去的问题,几乎都是 Java 端,应用程序特定配置文件中的一些可配置凭据,后者可以忽略 w.r.t.本题范围.
我们想提高应用程序的安全性。我们面临的问题是我们的应用程序必须能够 运行 离线,因此无论我们使用什么私钥来解密我们的数据,它都将与应用程序一起交付。我们正在考虑我们的选择,但其中 none 似乎最不安全:
- 保留密码 Java 端并使用
crypto
包 - 尽管如此,加密算法仍然可以识别,用于加密的密码仍必须公开存储在某个地方,因此可以相对容易地解密.此外,JAR 相对容易访问。 - 保留密码 C++ 端并使用函数
decryptKey
通过传递密码,用私钥解密 C++ 端,然后将其原样返回。在这种情况下,JNI 成为漏洞,因为很容易想到只构建您自己的 JAR,包含我们的 DLL,然后访问本机decryptKey
函数来检索纯文本密码。 - 将所有关键依赖逻辑转移到 C++。这毫无意义,因为我们必须将逻辑转移到不属于它的地方。此外,一些实现需要需要提供凭据的第 3 方 Java API,因此遗憾的是这不是一个选项。
问题
想必这在业界并不少见,那么最明智的处理方式是什么?目前,这些方法仅通过隐蔽性 安全性 引入,其有效性充其量是值得商榷的,最坏的情况下仅略高于零。行业内是否有处理此问题的标准程序?
首先,您的产品需要能够与能够保护您的私钥安全的产品集成。这些产品包括 TPM, HSM and KMS。这将证明对本地和基于云的生产环境非常有用。
其次,您应该实施 envelope encryption 机制,其中数据加密密钥使用将存储在 TPM/HSM/KMS 中的主密钥加密。加密后的数据加密密钥可以与数据一起存储。
第三,您应该实施 key rotation,每隔一段时间更换一次 master/data 密钥。
第四也是最后一点,您应该咨询 Information Security 而不是 Whosebug 以解决未来的强化问题。