Проверка доступности неограниченной криптографии
Как я могу проверить в Java-коде, доступна ли текущая JVM криптография с неограниченной силой?
9 ответов
Я думаю, что вы, вероятно, могли бы использовать Cipher.getMaxAllowedKeyLength (), одновременно сравнивая используемый вами шифр с известными списками "хороших", безопасных шифров, таких как AES.
Вот справочная статья, в которой перечислены ограничения юрисдикции максимального размера ключа, действовавшие в Java 1.4 (вероятно, они не изменились, если не изменился и закон - см. Ниже).
Если вы работаете в стране, в которой действуют криптографические ограничения на экспорт / импорт, вам нужно будет проконсультироваться с законодательством своей страны, но, вероятно, можно предположить, что в этих ситуациях у вас нет криптографии с неограниченной силой (по умолчанию) в вашей JVM. Другими словами, предполагая, что вы используете официальную JVM от Oracle, и вы живете в стране, против которой США нивелировали ограничения на экспорт криптографии (а поскольку Oracle является американской компанией, на нее будут распространяться эти требования). ограничения), тогда вы также можете предположить, что у вас нет неограниченной силы.
Конечно, это не мешает вам строить свое собственное и, таким образом, предоставлять себе неограниченную силу, но в зависимости от ваших местных законов это может быть незаконным.
Эта статья описывает ограничения на экспорт в другие страны, из Соединенных Штатов.
В том же духе, что и ответ Дана Круза, но с одной строкой кода и без исключений:
boolean limit = Cipher.getMaxAllowedKeyLength("RC5")<256;
Таким образом, полная программа может быть:
import javax.crypto.Cipher;
public class TestUCE {
public static void main(String args[]) throws Exception {
boolean unlimited =
Cipher.getMaxAllowedKeyLength("RC5") >= 256;
System.out.println("Unlimited cryptography enabled: " + unlimited);
}
}
Если вы работаете в Linux и установили JDK (но Beanshell недоступен), вы можете проверить с помощью runscript
Команда предоставляется с JDK.
jrunscript -e 'exit (javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") >= 256 ? 0 : 1);'; echo $?
Это возвращает 0
код состояния, если доступна неограниченная криптография, или 1
если нет в наличии. Ноль - это правильное возвращаемое значение "успех" для функций оболочки, а ненулевое значение указывает на сбой.
Как проверить, применяются ли ограничения, описано в методе. Cipher.getMaxAllowedKeyLength
:
Если установлены файлы политики неограниченной юрисдикции JCE,
Integer.MAX_VALUE
будет возвращен.
Это означает, что если любое значение отличается от (или даже ниже) Integer.MAX_VALUE
возвращается, что ограничения действительно применяются.
Еще больше информации в JavaDoc метода ниже:
/**
* Determines if cryptography restrictions apply.
* Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
* This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
*
* @return <code>true</code> if restrictions apply, <code>false</code> otherwise
*/
public static boolean restrictedCryptography() {
try {
return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
}
}
Обратите внимание, что, начиная с Java 9, по умолчанию устанавливаются неограниченные крипто-политики (а те, на которых влияют правила импорта / экспорта, должны вместо этого устанавливать ограниченные крипто-политики). Таким образом, этот код в основном потребуется для обратной совместимости и / или других сред выполнения.
Это полная версия для вставки копии для тестирования
import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
class Test {
public static void main(String[] args) {
int allowedKeyLength = 0;
try {
allowedKeyLength = Cipher.getMaxAllowedKeyLength("AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
System.out.println("The allowed key length for AES is: " + allowedKeyLength);
}
}
Бежать
javac Test.java
java Test
Если JCE не работает, выведите: 128
JCE работает что-то вроде: 2147483647
Вы можете проверить это за один шаг из командной строки, используя groovy:
groovysh -e 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
Если результат 2147483647
У вас неограниченная криптография.
На старых версиях Groovy вы должны удалить -e
:
groovysh 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
Если вы используете Linux, вы можете легко проверить это с помощью этой команды
java -version ; \
echo 'System.err.println(javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding").getMaxAllowedKeyLength("AES"));' \
| java -cp /usr/share/java/bsh-*.jar bsh.Interpreter >/dev/null
Если выходные данные примерно такие, криптография с неограниченной силой недоступна
java version "1.7.0_76"
Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
128
ПРИМЕЧАНИЕ: Пожалуйста, используйте ответ Джеффлунта или ответ Константина Спирова. Этот ответ не является верным, поскольку он всегда будет возвращаться true
, Я оставляю этот ответ здесь только потому, что на него есть ссылки в других местах в ответах и комментариях, и он полезен только в качестве ссылки.
Вы можете использовать следующее для инициализации static final boolean
где-то, что вы можете затем использовать для тестирования неограниченной криптографической поддержки (поскольку 256-битный AES поддерживается только в том случае, если установлена неограниченная политика).
boolean isUnlimitedSupported = false;
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES", "SunJCE");
kgen.init(256);
isUnlimitedSupported = true;
} catch (NoSuchAlgorithmException e) {
isUnlimitedSupported = false;
} catch (NoSuchProviderException e) {
isUnlimitedSupported = false;
}
System.out.println("isUnlimitedSupported=" + isUnlimitedSupported);
// set static final variable = isUnlimitedSupported;
Мне недавно пришлось добавить проверку JCE, и мое решение развилось до следующего фрагмента. Это был отличный сценарий, но его легко преобразовать в стандартный метод Java с помощью try catch. Это было проверено с Java 7 и Java 8.
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
// Make a blank 256 Bit AES Key
final SecretKey secretKey = new SecretKeySpec(new byte[32], "AES");
final Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// This line will throw a invalid key length exception if you don't have
// JCE Unlimited strength installed
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
// If it makes it here, you have JCE installed