Проверка доступности неограниченной криптографии - PullRequest
44 голосов
/ 31 октября 2011

Как я могу проверить в коде Java, доступна ли на текущей JVM криптография с неограниченной силой?

Ответы [ 9 ]

43 голосов
/ 22 декабря 2011

В том же духе, что и ответ Дана Круза, но с одной строкой кода и без исключений:

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);
  }
}
33 голосов
/ 30 апреля 2015

Если вы работаете в Linux и установили JDK (но Beanshell недоступен), вы можете проверить с помощью команды runscript, поставляемой с JDK.

jrunscript -e 'exit (javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") >= 256 ? 0 : 1);'; echo $?

Возвращает код состояния 0, если доступна неограниченная криптография, или 1, если она недоступна. Ноль - это правильное возвращаемое значение «успех» для функций оболочки, а ненулевое значение указывает на сбой.

25 голосов
/ 31 октября 2011

Я думаю, что вы, вероятно, могли бы использовать Cipher.getMaxAllowedKeyLength () , одновременно сравнивая используемый вами шифр с известными списками «хороших», безопасных шифров, таких как AES.

Вот справочная статья , в которой перечислены ограничения юрисдикции максимального размера ключа, действовавшие в Java 1.4 (вероятно, они не изменились, если не изменился и закон - см. Ниже).

Если вы работаете в стране, в которой действуют криптографические ограничения на экспорт / импорт, вам нужно будет проконсультироваться с законодательством своей страны, но, вероятно, в таких ситуациях можно предположить, что вы не иметь криптографию неограниченной силы (по умолчанию) в вашей виртуальной машине Java. Другими словами, если вы используете официальную JVM от Oracle , и вы живете в стране, против которой США нивелировали ограничения на экспорт криптографии (а поскольку Oracle является американской компанией, это будет подчиняться этим ограничениям), тогда вы также можете предположить, что у вас нет неограниченной доступной силы.

Конечно, , который не мешает вам построить свой собственный , и, таким образом, дает вам неограниченную силу, но в зависимости от ваших местных законов это может быть незаконным.

В этой статье изложены ограничения на экспорт в другие страны из Соединенных Штатов.

15 голосов
/ 22 ноября 2015

Способ проверки применения ограничений документирован в методе 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, по умолчанию устанавливаются неограниченные крипто-политики (вместо тех, на которые влияют правила импорта / экспорта, приходится вместо этого устанавливать крипто-политики limited ). Таким образом, этот код в основном потребуется для обратной совместимости и / или других сред выполнения.

5 голосов
/ 17 августа 2016

Это полная версия копии для вставки для тестирования

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

3 голосов
/ 11 февраля 2015

Если вы используете 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
2 голосов
/ 17 марта 2017

Вы можете проверить это за один шаг из командной строки, используя groovy:

groovysh -e 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'

Если результат 2147483647, у вас неограниченная криптография.

В более старой версии groovy вы должны удалить -e:

groovysh 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
0 голосов
/ 11 июля 2015

Мне недавно пришлось добавить проверку 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
0 голосов
/ 31 октября 2011

ПРИМЕЧАНИЕ : Пожалуйста, используйте ответ Джеффлунта или ответ Константина Спирова .Этот ответ не является верным, поскольку он всегда будет возвращать 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...