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

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

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

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

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

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

1 Ответ

0 голосов
/ 07 января 2019

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

...