是否可以在不提供整个转换的情况下检查特定密码块模式支持?

Is it possible to check for a specific cipher block mode support without providing a whole transform?

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

我知道我可以尝试使用转换创建密码,例如AES/GCM/PKCS5Padding 并捕获 NoSuchAlgorithmException,但可能仅针对 特定 转换抛出该异常,而不仅仅是因为不支持 GCM 模式本身(在 [=22 内) =]任意变换).

我也可以只检查 JVM 版本,但对于使用第 3 方加密库(例如 BouncyCastle)或具有内置支持的 JVM 的环境,这不是有效的检查另一家恰好支持 GCM 的供应商。

我宁愿跳过测试 只有 如果 GCM 一般不受支持,而不仅仅是我在代码中选择的特定(和完整)转换不受支持支持。

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

是的,您可以遍历提供者和服务并寻找一个是密码且名称中包含 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 的实现。此外,除了 "NoPadding" 之外没有任何参数对 GCM 模式有意义(无论如何在算法字符串中,我当然不是在谈论 GCCMParameterSpec)。

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