0

我有一个单元测试在 Java 8+ 中通过并在 Java 7 上失败,因为 Java 7 和更早版本似乎不支持 GCM 模式。

我知道我可以尝试使用例如AES/GCM/PKCS5Padding和 catch的转换来创建密码NoSuchAlgorithmException,但是该异常可能仅针对该特定转换而引发,而不仅仅是因为不支持 GCM 模式本身(在任何转换中)。

我也可以只检查 JVM 版本,但这对于正在使用 3rd 方加密库(例如 BouncyCastle)的环境或具有来自另一个供应商的内置支持的 JVM 的环境来说不是有效的检查包括对 GCM 的支持。

我宁愿在不支持 GCM 的情况下跳过测试,而不仅仅是在不支持我在代码中选择的特定(和完整)转换的情况下。

是否可以从 Java 中检测支持的密码块模式?还是只能尝试特定的转换并查看它是否有效?

4

1 回答 1

2

是的,您可以遍历提供者和服务,并寻找一个密码服务,并在名称中包含 GCM,例如

Provider[] provs = Security.getProviders();
for (Provider prov : provs) {
    Set<Service> services = prov.getServices();
    for (Service service : services) {
        if (!service.getType().matches("(?i)Cipher")) {
            break;
        }
        String algo = service.getAlgorithm();
        if (algo.matches("(?i).*/GCM/.*")) {
            System.out.println(service);
        }
    }
}

请注意,您可能想要检查旧 Java 运行时的无限制加密,例如使用我的答案here

您可能要考虑 GCM 仅对 128 位密码有效,并且您不太可能找到不使用 AES 的实现。此外,除了对 GCM 模式有意义之外,没有任何其他参数"NoPadding"(无论如何,在算法字符串中,我当然不是在谈论GCCMParameterSpec)。

请注意,以后的提供者可能不会返回"AES/GCM/NoPadding"而是返回"AES_128/GCM/NoPadding""AES_192/GCM/NoPadding"而是返回"AES_256/GCM/NoPadding"。这也会影响Provider#getService(type, algorithm)调用,使其在您想要检查时无用"AES/GCM/NoPadding",即具有任何有效密钥大小的 AES。

于 2019-01-07T00:07:25.220 回答