Можно ли проверить наличие поддержки режима конкретного блока шифрования, не предоставляя полного преобразования?

У меня есть модульный тест, который проходит в Java 8+ и не проходит в Java 7, потому что режим GCM, похоже, не поддерживается в Java 7 и более ранних версиях.

Я знаю, что я могу попытаться создать шифр с помощью преобразования, например AES/GCM/PKCS5Padding и поймать NoSuchAlgorithmException, но это исключение может быть выдано только для этого конкретного преобразования, а не только потому, что сам режим GCM не поддерживается (в любом преобразовании).

Я также могу просто проверить версию JVM, но это не будет действительной проверкой для среды, в которой используется сторонняя криптографическая библиотека (например, BouncyCastle) или JVM со встроенной поддержкой другого поставщика, что происходит с включить поддержку GCM.

Я бы предпочел пропустить тест, только если GCM в целом не поддерживается, а не только если не поддерживается конкретное (и полное) преобразование, которое я выбрал в своем коде.

Можно ли определить поддерживаемые режимы шифрования из Java? Или можно только попробовать конкретное преобразование и посмотреть, работает ли оно?

1 ответ

Решение

Да, вы можете перебирать поставщиков и сервисы и искать сервис, который является шифром и содержит имя 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, например, используя мой ответ здесь.

Возможно, вы захотите учесть, что GCM действителен только для 128-битных шифров и что маловероятно, что вы найдете реализации, которые не используют AES. Кроме того, нет никаких параметров, кроме "NoPadding" это имеет смысл для режима GCM (в любом случае в строке алгоритма я не говорю о GCCMParameterSpec конечно).

Помните, что более поздние поставщики могут не вернуться "AES/GCM/NoPadding" но вернись "AES_128/GCM/NoPadding", "AES_192/GCM/NoPadding" а также "AES_256/GCM/NoPadding" вместо. Это также влияет на Provider#getService(type, algorithm) вызов, делая его бесполезным, если вы хотите проверить "AES/GCM/NoPadding" AES с любым допустимым размером ключа.

Другие вопросы по тегам