Безпека Java: Незаконні розміри ключа або параметри за замовчуванням?


409

Я задавав питання про це раніше, але на це не відповів правильно і нікуди не привів.

Тож я уточнив декілька деталей проблеми і дуже хотів би почути ваші ідеї щодо того, як я можу це виправити чи що мені слід спробувати.

У мене на моєму сервері Linux встановлений Java 1.6.0.12, і код нижче працює просто чудово.

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 jarddiction Policy Files. І тоді це спрацює.
anjanb

5
Оновити відповідь на @AniketThakur Оскільки Java 9 та Java 8u151 більше не потрібно завантажувати та вручну встановлювати файли політики юрисдикції. Щоб увімкнути необмежену криптографію, можна використовувати нове властивість crypto.policy Security. Якщо нове властивість безпеки (crypto.policy) встановлено у файлі java.security або було встановлено динамічно за допомогою виклику Security.setProperty () перед ініціалізацією структури JCE, це налаштування буде виконано. За замовчуванням властивість буде не визначено.
Marcin Kłopotek

Відповіді:


722

Швидше за все, у вас зараз не встановлений файл необмеженої міцності.

Можливо, вам доведеться завантажити цей файл:

Файли політик з необмеженою силою юрисдикції для розширення криптографії Java (JCE) 6

Розширення файлів політики криптографії Java (JCE) Необмежені файли політики юрисдикції 7 Завантажити

Розширення файлів політики з обмеженою силою юрисдикції Java (розширення криптографії Java) (JCE) 8 Завантаження (потрібне лише для версій до Java 8 u162)

Витягніть файли jar із zip та збережіть їх ${java.home}/jre/lib/security/.


2
@JamesBlack - Так, і щоб переконатися , що всі підстави покриті я поставити під флягу в Java/jre/lib/security, Java/jdk/lib/securityі Java/jdk/jre/lib/security. Запуск "java -version" повертає очікувані деталі.
aroth

5
Для SDK IBM (наприклад, WebSphere) завантажте файли політики необмеженої юрисдикції з www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
silentmint

4
Оскільки Java 9 та Java 8u151 більше не потрібно завантажувати та вручну встановлювати файли політики юрисдикції. Щоб увімкнути необмежену криптографію, можна використовувати нове властивість crypto.policy Security. Якщо нове властивість безпеки (crypto.policy) встановлено у файлі java.security або було встановлено динамічно за допомогою виклику Security.setProperty () перед ініціалізацією структури JCE, це налаштування буде виконано. За замовчуванням властивість буде не визначено.
Marcin Kłopotek

4
Отже, ця схвалена відповідь застаріла і застаріла. Як ми upvote або придушити цю відповідь , так що stackoverflow.com/a/46857694/2808798 може бути «прийнятий» відповідь?
Джессі Адельман

3
@JesseAdelman - На жаль, це майже 7 років, не багато чого можна зробити. Хто б не питав, потрібно було б це змінити.
Джеймс Блек

54

Файли юрисдикції JRE / JDK / Java 8 можна знайти тут:

Розширення файлів політики криптографії Java (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 :)
Fluf

42

Для JAVA 7 посилання для завантаження - jce-7

Скопіюйте дві завантажені банки в Java \ jdk1.7.0_10 \ jre \ lib \ security
Візьміть резервну копію старих банок, щоб бути надійніше.

Для JAVA 8 посилання для завантаження jce-8-скачати
Скопіюйте завантажені банки на Java \ jdk1.8.0_45 \ jre \ lib \ security
Візьміть резервну копію старих банок, щоб вони були надійнішими.


39

У Java 9, Java 8u161 , Java 7u171 та Java 6u181 обмеження відключено за замовчуванням. Дивіться проблему в базі даних Java Bug .


Починаючи з 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
}

Кредити: Дельта


4
Зауважте, що це може порушити ліцензійну угоду Java SE: D. JAVA ТЕХНОЛОГІЧНІ ОБМЕЖЕННЯ. Ви не можете створювати, змінювати або змінювати поведінку ліцензіатів або уповноважувати своїх ліцензіатів створювати, змінювати або змінювати поведінку класів, інтерфейсів чи підпакетів, які будь-яким чином ідентифікуються як "java", "javax", " javafx "," sun "," oracle "або аналогічна умова, визначена Oracle у будь-якому позначенні конвенції про іменування. [...] Джерело
SimMac

Величезне спасибі


16

Я зазнав таку ж помилку під час використання Windows 7 x64, Eclipse та JDK 1.6.0_30. У папці установки JDK є jreпапка. Це спочатку мене відкинуло, коли я додав вищезгадані банки в папку безпеки / безпеки JDK без удачі. Повний шлях:

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

Завантажте та витягніть у цю jceпапку файли, що містяться в папці цього архіву .


16

У Java за замовчуванням AES підтримує 128-розрядний ключ, якщо ви плануєте використовувати 192-бітний або 256-бітний ключ, java complier закине неправомірний виняток розміру ключа, який ви отримуєте.

Рішення є переможцем та запропонував Джеймс, вам потрібно завантажити JCE (розширення криптографії Java) відповідно до вашої версії 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 у папці безпеки не працює на unix, тому я пропоную скопіювати папку безпеки спочатку на робочий стіл, замінити папку @ Desktop / security банку, видалити папку безпеки з / jre / lib / & перемістіть папку безпеки Desktop в / 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 / security вже одного разу, коли я встановив Java .. І я не міг знайти core / lib / jce, до речі, у своїй інсталяційній папці 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 підтримує лише шифр AES на 128 бітах (16 байт) для шифрування. Якщо вам не потрібно більше ніж підтримується за замовчуванням, перед використанням можна обрізати ключ до потрібного розміру 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. Також відомий як алгоритм Рійндейла Джоан Демен і Вінсент Ріджмен, AES - це 128-бітний блоковий шифр, що підтримує клавіші 128, 192, і 256 біт.
zaph

Це може бути правдою, але це вимагається лише кожною версією Java для підтримки 128-розрядних версій, як зазначено в документації на клас. Перевірте це самостійно, і ви побачите, що вам знадобиться політика з відповіді Джеймса Блека, щоб виконати інші ключові розміри
keaplogik

Будь-яка реалізація AES, яка не підтримувала 256-бітні ключі, була б по суті марною, оскільки не змогла б розшифрувати значну кількість шифрів AES за допомогою 256-бітних ключів.
zaph

1
Якщо потрібен 256-розрядний ключ, найкращим рішенням, мабуть, єдиним рішенням є встановлення файлу Policy, якщо це необхідно, а не усікання ключа, що потенційно послаблює захист, і може бути неможливим у разі сумісності.
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 , політика юрисдикції необмеженої сили включає в себе Java 8, але за замовчуванням не використовується. Щоб увімкнути це, потрібно відредагувати файл java.security у <java_home>/jre/lib/security(для JDK) або <java_home>/lib/security(для JRE). Відміняйте (або включіть) рядок

    crypto.policy=unlimited

    Переконайтесь, що ви редагуєте файл за допомогою редактора, запущеного як адміністратор. Зміна політики набирає чинності лише після перезавантаження JVM

Перед оновленням Java 8 відповіді залишаються дійсними. Завантажте файли політик JCE Unlimited Strength Jurisdiction Policy і замініть їх.

Щоб отримати докладніші відомості, ви можете ознайомитись з моїм особистим повідомленням у блозі нижче - Як встановити файли політики необмеженої юрисдикції з розширенням Java Cryptography Extension (JCE)


1

Є два варіанти вирішення цього питання

варіант № 1: використовувати сертифікат з меншою довжиною RSA 2048

варіант 2: ви оновите дві банки в jre\lib\security будь-якій версії Java, яку ви використовуєте http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

або ви використовуєте веб-сферу IBM або будь-який сервер додатків, що використовують її Java. Основна проблема, з якою я стикався, я використовував сертифікацію з максимальною довжиною, коли я розгортав вуха на вебсфері, викидається той самий виняток

Java Security: Illegal key size or default parameters?

я оновив папку Java intsalled у веб-сфері з двома банками 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.забезпеченість і незмінність

#crypto.policy=unlimited

до

crypto.policy=unlimited
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.