Безопасность Java: недопустимый размер ключа или параметры по умолчанию?
Я задавал вопрос об этом ранее, но он не получил правильного ответа и ни к чему не привел.
Итак, я прояснил несколько деталей по этой проблеме, и мне бы очень хотелось услышать ваши идеи о том, как я могу это исправить или что я должен попробовать.
У меня установлена 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. В первом нет дополнительных провайдеров.
* Предыдущий вопрос здесь.
20 ответов
Скорее всего, сейчас у вас не установлен файл неограниченной силы.
Вам может понадобиться скачать этот файл:
Файлы политик юрисдикции с неограниченной силой расширения Java Cryptography Extension (JCE) 6
Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 7 Загрузить
Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 8 Загрузка (требуется только для версий до Java 8 u162)
Извлеките файлы jar из почтового индекса и сохраните их в ${java.home}/jre/lib/security/
,
Файлы юрисдикции JRE/JDK/Java 8 можно найти здесь:
Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 8 Загрузить
Как сказал Джеймс выше:
Установите файлы в ${java.home}/jre/lib/security/
,
В Java 9, Java 8u161, Java 7u171 и Java 6u181 ограничение теперь отключено по умолчанию. Смотрите проблему в Java Bug Database.
Начиная с Java 8u151 вы можете программно отключить ограничение.
В более старых выпусках файлы юрисдикции JCE приходилось загружать и устанавливать отдельно, чтобы JDK мог использовать неограниченную криптографию. Этапы загрузки и установки больше не нужны.
Вместо этого вы можете теперь вызвать следующую строку перед первым использованием классов JCE (т.е. предпочтительно сразу после запуска приложения):
Security.setProperty("crypto.policy", "unlimited");
Для JAVA 7 ссылка для скачивания - jce-7-download
Скопируйте два скачанных файла jar в Java\jdk1.7.0_10\jre\lib\security
Сделайте резервную копию старых банок, чтобы быть на более безопасной стороне.
Для JAVA 8 ссылка для скачивания - jce-8-download
Скопируйте загруженные файлы в формате Java\jdk1.8.0_45\jre\lib\security
Сделайте резервную копию старых банок, чтобы быть на более безопасной стороне.
Это решение только для кода. Не нужно скачивать или связываться с файлами конфигурации.
Это решение на основе отражения, протестировано на 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
В Java по умолчанию AES поддерживает 128-битный ключ, если вы планируете использовать 192-битный или 256-битный ключ, java complier выдаст исключение недопустимого размера ключа, которое вы получаете.
Решение, как предложил Виктор и Джеймс, вам нужно будет загрузить JCE (Java Cryptography Extension) в соответствии с вашей версией JRE (java6, java7 или java8).
Почтовый индекс JCE содержит следующие JAR:
- local_policy.jar
- 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
Я столкнулся с той же ошибкой при использовании 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
папка этого архива в эту папку.
"Файлы политики юрисдикции неограниченной силы расширения Java Cryptography Extension (JCE) 6"
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Проблема заключается в содержимом файла 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.
Здесь короткое обсуждение того, что кажется этой проблемой. Страница, на которую она ссылается, кажется, пропала, но один из ответов может быть тем, что вам нужно:
Действительно, копирование US_export_policy.jar и local_policy.jar из core / lib / jce в $JAVA_HOME/jre/lib/security помогло. Благодарю.
Я также получил проблему, но после замены существующего загруженным (из JCE), один решил проблему. Новые крипто файлы предоставили неограниченную силу.
Если вы используете дистрибутив Linux с apt и добавили PPA webupd8, вы можете просто запустить команду
apt-get install oracle-java8-unlimited-jce-policy
Другие обновления:
- Файлы политики неограниченной юрисдикции включены в Java 9 и используются по умолчанию
- Начиная с Java 8 Update 161, Java 8 по умолчанию использует Политику неограниченной юрисдикции.
Начиная с 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)
По умолчанию 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);
}
Начиная с Java 9 или 8u151, вы можете использовать комментарий строки в файле:
<JAVA_HOME>/jre/lib/security/java.security
И изменить:
#crypto.policy=unlimited
в
crypto.policy=unlimited
Недавно я столкнулся с той же проблемой в версии Java 1.8.0_102. Обновлен до 1.8.0_231, и проблема решена.
JDK по умолчанию поддерживает шифрование только через 128-битные ключи из-за американских ограничений. Поэтому для поддержки шифрования ключа длиной 256 бит мы должны заменить local_policy.jar
а также US_export_policy.jars
в $JAVA_HOME/java-8-oracle/jre/lib/security
папка иначе даст:
java.security.InvalidKeyException: недопустимый размер ключа или значение по умолчанию
И банку, и детальную концепцию можно понять по ссылке:
Есть два варианта решения этой проблемы
Вариант № 1: использовать сертификат с меньшей длиной RSA 2048
Вариант № 2: вы обновите две банки в 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
Убедитесь, что вы используете последнюю версию JDK / JRE.
В моем случае я поместил JCE в папку JRE, но это не помогло. Это произошло потому, что я запускал свой проект из IDE напрямую (используя JDK).
Затем я обновил JDK и JRE до последней версии (1.8.0_211), и проблема исчезла.
Более подробная информация: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157
Загрузите файлы JCE по ссылке ниже для Java 6
https://www.oracle.com/java/technologies/jce-6-download.html
Загрузите файлы JCE по ссылке ниже для Java 8
https://www.oracle.com/java/technologies/javase-jce8-downloads.html
Скопируйте файлы, загруженные по указанной выше ссылке, и перейдите в установленный каталог JDK.
/Users/ik/jdk1.8.0_72/jre/lib/security
Вставьте и замените файлы из каталога. Перезагрузите приложение, и ошибка должна быть устранена.
Вы должны пойти туда
/jdk1.8.0_152 | / JRE | /lib | / безопасность | java.security и раскомментируйте
#crypto.policy=unlimited
в
crypto.policy=unlimited