Безопасность Java: недопустимый размер ключа или параметры по умолчанию?


409

Я задавал вопрос об этом ранее, но он не получил правильного ответа и ни к чему не привел.

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

У меня установлена Java 1.6.0.12 на моем сервере Linux, и код ниже работает просто отлично.

String key = "av45k1pfb024xa3bl359vsb4esortvks74sksr5oy4s5serondry84jsrryuhsr5ys49y5seri5shrdliheuirdygliurguiy5ru";
try {
    Cipher c = Cipher.getInstance("ARCFOUR");

    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "ARCFOUR");
    c.init(Cipher.DECRYPT_MODE, secretKeySpec);

    return new String(c.doFinal(Hex.decodeHex(data.toCharArray())), "UTF-8");

} catch (InvalidKeyException e) {
    throw new CryptoException(e);
}

Сегодня я установил Java 1.6.0.26 на своем сервере, и когда я пытаюсь запустить свое приложение, я получаю следующее исключение. Я предполагаю, что это как-то связано с конфигурацией установки Java, потому что она работает в первой, но не работает в более поздней версии.

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at my.package.Something.decode(RC4Decoder.java:25) ~[my.package.jar:na]
    ... 5 common frames omitted

Строка 25 : c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Примечания:
* java.security в java-каталоге сервера 1.6.0.12 почти полностью соответствует файлу java.security 1.6.0.26. В первом нет дополнительных провайдеров.
* Предыдущий вопрос здесь .



4
Это также может быть выдано как ошибка: Caused by: java.security.InvalidKeyException: Illegal key size(без «или параметров по умолчанию») в Java 8
hackajar

Просто используйте OpenJDK, и он будет работать.
Родриго Асенсио

@RodrigoAsensio: я использую OpenJDK, и он не работает с ним. Вы должны установить неограниченные jar-файлы с файлами политики Strength Jurisdiction. И тогда это будет работать.
anjanb

5
Обновите ответ @AniketThakur. Начиная с Java 9 и Java 8u151 больше нет необходимости загружать и вручную устанавливать файлы политики юрисдикции. Чтобы включить неограниченную криптографию, можно использовать новое свойство безопасности crypto.policy. Если новое свойство Security (crypto.policy) установлено в файле java.security или было установлено динамически с помощью вызова Security.setProperty () до инициализации инфраструктуры JCE, этот параметр будет принят. По умолчанию свойство будет неопределенным.
Марцин Клопотек

Ответы:


722

Скорее всего, у вас сейчас не установлен файл неограниченной силы.

Вам может понадобиться скачать этот файл:

Файлы политик юрисдикции с неограниченной силой расширения Java Cryptography Extension (JCE) 6

Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 7 Загрузить

Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 8 Загрузить (требуется только для версий до Java 8 u162)

Извлеките файлы фляги из почтового индекса и сохраните их в ${java.home}/jre/lib/security/.


2
@JamesBlack - Да, и чтобы убедиться, что все базы покрыты, я поместил в JAR Java/jre/lib/security, Java/jdk/lib/securityи Java/jdk/jre/lib/security. Запуск 'java -version' возвращает ожидаемые детали.
aroth

5
Для IBM SDK (например, WebSphere) загрузите файлы политики неограниченной юрисдикции с www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
quietmint

4
Начиная с Java 9 и Java 8u151 больше нет необходимости загружать и вручную устанавливать файлы политики юрисдикции. Чтобы включить неограниченную криптографию, можно использовать новое свойство безопасности crypto.policy. Если новое свойство Security (crypto.policy) установлено в файле java.security или было установлено динамически с помощью вызова Security.setProperty () до инициализации инфраструктуры JCE, этот параметр будет принят. По умолчанию свойство будет неопределенным.
Марцин Клопотек

4
Таким образом, этот ответ с поправками уже устарел и устарел. Как мы можем подтвердить или подавить этот ответ, чтобы stackoverflow.com/a/46857694/2808798 мог быть «принятым» ответом?
Джесси Адельман

3
@JesseAdelman - К сожалению, это почти 7 лет, мало что можно сделать. Кто бы ни спросил, нужно будет это изменить.
Джеймс Блэк,

54

Файлы юрисдикции JRE / JDK / Java 8 можно найти здесь:

Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 8 Загрузить

Как сказал Джеймс выше:
установите файлы в ${java.home}/jre/lib/security/.


2
Пробовал использовать 6 и 7, но они не работали. Пришлось установить 8. Спасибо.
Джейсон Ким

9
Новый выпуск JDK 8u151 имеет «Новое свойство безопасности для управления политикой шифрования». Теперь это изменение свойства для переключения. Суть: удалите «#» из строки «# crypto.policy = unlimited» в «lib \ security \ java.security», чтобы включить использование 256-битных ключей. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
полушарие

1
Спасибо! Поскольку это свойство безопасности, вы также можете вызвать Security.setProperty ("crypto.policy", "unlimited"). Источник: ссылка
@hemisphire

42

Для JAVA 7 ссылка для скачивания jce-7-download

Скопируйте два скачанных файла jar в Java \ jdk1.7.0_10 \ jre \ lib \ security
Сделайте резервную копию старых чтобы они были более безопасными.

Для JAVA 8 ссылка для скачивания - jce-8-download.
Скопируйте загруженные файлы jar в Java \ jdk1.8.0_45 \ jre \ lib \ security.
Сделайте резервную копию старых файлов jar, чтобы быть на более безопасной стороне.


39

В Java 9, Java 8u161 , Java 7u171 и Java 6u181 ограничение теперь отключено по умолчанию. Смотрите проблему в Java Bug Database .


Начиная с Java 8u151 вы можете программно отключить ограничение.

В более старых выпусках файлы юрисдикции JCE приходилось загружать и устанавливать отдельно, чтобы JDK мог использовать неограниченную криптографию. Этапы загрузки и установки больше не нужны.

Вместо этого вы можете теперь вызвать следующую строку перед первым использованием классов JCE (т.е. предпочтительно сразу после запуска приложения):

Security.setProperty("crypto.policy", "unlimited");

А как насчет Android? На каком уровне API могут быть разрешены эти методы ограничения?
TheRealChx101

31

Это решение только для кода . Не нужно скачивать или связываться с файлами конфигурации.

Это решение на основе отражения, протестировано на Java 8

Вызовите этот метод один раз, в начале вашей программы.

// Импорт

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

// метод

public static void fixKeyLength() {
    String errorString = "Failed manually overriding key-length permissions.";
    int newMaxKeyLength;
    try {
        if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
            Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissionCollection = con.newInstance();
            Field f = c.getDeclaredField("all_allowed");
            f.setAccessible(true);
            f.setBoolean(allPermissionCollection, true);

            c = Class.forName("javax.crypto.CryptoPermissions");
            con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissions = con.newInstance();
            f = c.getDeclaredField("perms");
            f.setAccessible(true);
            ((Map) f.get(allPermissions)).put("*", allPermissionCollection);

            c = Class.forName("javax.crypto.JceSecurityManager");
            f = c.getDeclaredField("defaultPolicy");
            f.setAccessible(true);
            Field mf = Field.class.getDeclaredField("modifiers");
            mf.setAccessible(true);
            mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
            f.set(null, allPermissions);

            newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
        }
    } catch (Exception e) {
        throw new RuntimeException(errorString, e);
    }
    if (newMaxKeyLength < 256)
        throw new RuntimeException(errorString); // hack failed
}

Кредиты: Delthas


4
Обратите внимание, что это может нарушать лицензионное соглашение Java SE: D. ОГРАНИЧЕНИЯ JAVA TECHNOLOGY. Вы не можете создавать, изменять или изменять поведение или разрешать своим лицензиатам создавать, изменять или изменять поведение классов, интерфейсов или подпакетов, которые в любом случае определены как «java», «javax», « javafx "," sun "," oracle "или подобное соглашение, указанное Oracle в обозначении любого соглашения об именах. [...] источник
SimMac

Большое спасибо


16

Я столкнулся с той же ошибкой при использовании Windows 7 x64, Eclipse и JDK 1.6.0_30. В папке установки JDK есть jreпапка. Это сначала отбросило меня, когда я безуспешно добавлял вышеупомянутые jar-файлы в папку lib / security JDK. Полный путь:

C:\Program Files\Java\jdk1.6.0_30\jre\lib\security

Загрузите и извлеките файлы, содержащиеся в jceпапке этого архива, в эту папку.


16

В Java по умолчанию AES поддерживает 128-битный ключ, если вы планируете использовать 192-битный или 256-битный ключ, java complier выдаст исключение недопустимого размера ключа, которое вы получаете.

Решение, как предложил Виктор и Джеймс, вам нужно будет загрузить JCE (Java Cryptography Extension) в соответствии с вашей версией JRE (java6, java7 или java8).

Почтовый индекс JCE содержит следующие JAR:

  1. local_policy.jar
  2. US_export_policy.jar

Вам необходимо заменить эти банки <JAVA_HOME>/jre/lib/security . если вы работаете в системе Unix, вероятно, будет ссылаться на/home/urs/usr/lib/jvm/java-<version>-oracle/

Иногда простая замена local_policy.jar, US_export_policy.jar в папке security не работает на unix, поэтому я предлагаю сначала скопировать папку security на рабочий стол, заменить папку jar @ Desktop / security, удалить папку security из / jre / lib / & переместите папку безопасности рабочего стола в / jre / lib /.

напр .: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib


5

Там очень краткое обсуждение того , что , как представляется, этот вопрос здесь . Страница, на которую она ссылается, кажется, пропала, но один из ответов может быть тем, что вам нужно:

Действительно, копирование US_export_policy.jar и local_policy.jar из core / lib / jce в $ JAVA_HOME / jre / lib / security помогло. Спасибо.


Спасибо, но у меня была US_export_policy.jarи local_policy.jarв моем Lib / папку безопасности уже когда - то я установил Java .. И я не смог найти ядро / Библиотека / ОКО кстати в моей папке установки Java.
Рихардс

5

проблема заключается в содержимом файла default_local.policy в local_policy.jar в папке jre \ lib \ security , если вы устанавливаете JRE:

// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.

grant {
    permission javax.crypto.CryptoPermission "DES", 64;
    permission javax.crypto.CryptoPermission "DESede", *;
    permission javax.crypto.CryptoPermission "RC2", 128,
                                     "javax.crypto.spec.RC2ParameterSpec", 128;
    permission javax.crypto.CryptoPermission "RC4", 128;
    permission javax.crypto.CryptoPermission "RC5", 128,
          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
    permission javax.crypto.CryptoPermission "RSA", *;
    permission javax.crypto.CryptoPermission *, 128;
};

если вам не нужны действующие настройки по всему миру, вы можете просто отредактировать этот файл и изменить его содержимое на

// Country-specific policy file for countries with no limits on crypto strength.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission;
};

это то, что получится, если вы загрузите JCE из Oracle.


4

Я также получил проблему, но после замены существующего загруженным (от JCE), один решил проблему. Новые крипто файлы предоставили неограниченную силу.


2

По умолчанию Java поддерживает только 128-битный (16 байт) размер ключа AES для шифрования. Если вам не нужно больше, чем поддерживается по умолчанию, вы можете обрезать ключ до нужного размера перед использованием Cipher. См Javadoc для поддерживаемых ключей по умолчанию.

Это пример генерации ключа, который будет работать с любой версией JVM без изменения файлов политики. Используйте по своему усмотрению.

Вот хорошая статья о том, имеют ли значение ключи от 128 до 256 ключей в блоге AgileBits

SecretKeySpec getKey() {
    final pass = "47e7717f0f37ee72cb226278279aebef".getBytes("UTF-8");
    final sha = MessageDigest.getInstance("SHA-256");

    def key = sha.digest(pass);
    // use only first 128 bit (16 bytes). By default Java only supports AES 128 bit key sizes for encryption.
    // Updated jvm policies are required for 256 bit.
    key = Arrays.copyOf(key, 16);
    return new SecretKeySpec(key, AES);
}

Документация классов Cipher указывает на допустимые размеры ключей для каждого типа шифрования.
keaplogik

См. Документ Oracle Алгоритмы шифрования (шифрования) AES: расширенный стандарт шифрования, определенный NIST в FIPS 197. Также известный как алгоритм Rijndael Джоан Даемен и Винсент Раймен, AES - это 128-битный блочный шифр, поддерживающий ключи 128, 192, и 256 бит.
zaph

Это может быть правдой, но для каждой версии Java требуется только поддержка 128-битного кода, как указано в документации класса. Попробуйте сами, и вы обнаружите, что вам понадобится баночка с политикой из ответа Джеймса Блэка для других ключевых размеров
keaplogik

Любая реализация AES, которая не поддерживает 256-битные ключи, будет по существу бесполезной, потому что она не сможет расшифровать значительное количество шифрований AES с использованием 256-битных ключей.
Zaph

1
Если нужен 256-битный ключ, лучшее решение, возможно, единственное решение, это установить файл политики, если это необходимо, а не обрезать ключ, потенциально ослабляющий безопасность и не способный в случае взаимодействия.
zaph

2

Начиная с Java 9 или 8u151, вы можете использовать комментарий строки в файле:

<JAVA_HOME>/jre/lib/security/java.security

И изменить:

#crypto.policy=unlimited

в

crypto.policy=unlimited

2

Если вы используете дистрибутив Linux с apt и добавили webupd8 PPA, вы можете просто запустить команду

apt-get install oracle-java8-unlimited-jce-policy

Другие обновления:

  1. Файлы политики неограниченной юрисдикции включены в Java 9 и используются по умолчанию
  2. Начиная с Java 8, обновление 161 , Java 8 по умолчанию использует Политику неограниченной юрисдикции.
  3. Начиная с Java 8 Update 151 , политика неограниченной юрисдикции включена в Java 8, но по умолчанию не используется. Чтобы включить его, вам нужно отредактировать файл java.security в <java_home>/jre/lib/security(для JDK) или <java_home>/lib/security(для JRE). Раскомментируйте (или включите) строку

    crypto.policy=unlimited

    Убедитесь, что вы редактируете файл с помощью редактора, запускаемого от имени администратора. Изменение политики вступает в силу только после перезапуска JVM

До Java 8 Обновление 151 остальные ответы остаются в силе. Загрузите файлы политики неограниченной юрисдикции JCE и замените их.

Для получения более подробной информации вы можете обратиться к моему личному сообщению в блоге ниже - Как установить файлы политик неограниченной юрисдикции Java Cryptography Extension (JCE)


1

Есть два варианта решения этой проблемы

Вариант № 1: использовать сертификат с меньшей длиной RSA 2048

вариант № 2: вы будете обновлять два jar-файла в jre\lib\security любом используемом java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

или вы используете IBM websphere или любой сервер приложений, который использует его Java. основная проблема, с которой я столкнулся, я использовал сертификацию с максимальной длиной, когда я развернул уши на веб-сфере, выдается то же исключение

Java Security: Illegal key size or default parameters?

я обновил вложенную папку Java в websphere двумя банками https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

Вы можете проверить ссылку в ссылке https://www-01.ibm.com/support/docview.wss?uid=swg21663373


1

Убедитесь, что вы используете последнюю версию JDK / JRE .

В моем случае я поместил JCE в папку JRE, но это не помогло. Это произошло потому, что я запускал свой проект из IDE напрямую (используя JDK).

Затем я обновил JDK и JRE до последней версии (1.8.0_211), и проблема исчезла.

Более подробно: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157


1

JDK по умолчанию поддерживает шифрование только через 128-битные ключи из-за американских ограничений. Таким образом, для поддержки шифрования из 256-битного ключа мы должны заменить его local_policy.jarи US_export_policy.jarsв $JAVA_HOME/java-8-oracle/jre/lib/securityпапке, иначе это даст:

java.security.InvalidKeyException: недопустимый размер ключа или значение по умолчанию


0

Вы должны пойти туда

/jdk1.8.0_152 | / JRE | / lib | / безопасность | java.security и раскомментируйте

#crypto.policy=unlimited

в

crypto.policy=unlimited
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.