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