为了使用Java实现加密,我使用JCE,这很好又有趣。 有人告诉我,选择加密货币提供商比使用默认提供商更好。
我需要选择用于对称密钥生成的提供商。此代码使用(在 CBC 模式下使用 AES):
Key sharedKey = (KeyGenerator.getInstance("AES/CBC/PKCS5PADDING", PROVIDER1).generateKey();
对于此代码使用的非对称文本加密(在 ECB 模式下使用 RSA):
Cipher rsaEncryptor = Cipher.getInstance("RSA/ECB/PKCS1Padding",PROVIDER2);
我的问题是我应该如何选择PROVIDER1和PROVIDER2?
例如,我看到“SunJCE”是一个有据可查的提供商,但我不认为这是选择它的“足够好”的理由。
有人吗?
一般来说,您应该坚持使用默认提供程序,除非有令人信服的理由不这样做。对您的提供程序进行硬编码有一个严重的缺点,即您的代码不允许您在不重写代码的情况下更改您的提供程序。
我认为直接选择提供商的唯一原因是确保满足一些安全限制,而其他提供商不会存在这些限制。例如,如果“实施”需要获得 FIPS 或通用标准认证,就属于这种情况。然而,在实践中,这也可以通过延迟提供商选择来实现。
以下段落您仍然可以通过在运行时的
getInstance("...", "SunJCE"); // not recommended vs. getInstance("..."); // recommended
java.security
路径中的
jre/lib/security
文件中赋予其他提供程序更高的优先级(较低优先级指示符,1 是最高优先级)来允许使用其他提供程序。Java 如今还通过使用特定的 Key
派生类来使用延迟提供者选择。如果 Oracle 提供程序无法识别所使用的类,那么它将检查是否应使用另一个已注册的提供程序,即使它的优先级较低。例如,这意味着对私钥的引用(其中实际密钥存储在特定密钥存储中)可以由正确的提供者处理。例如,情况可能就是这样。私钥存储在智能卡、HSM 或设备特定 (Android) 密钥库中。
如果在这一切之后,您仍然想使用getInstance("Algorithm", "Provider")
指定提供程序,那么使提供程序字符串可配置可能是一个好主意(例如使用属性和使用
myConfig.getProperty("Provider")
)。这将允许您切换到另一个提供商而无需更改代码。另一方面,您可能想确保此配置文件受到保护/签名。在这种情况下,它需要额外的安全级别。