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

Когда я запускаю этот код в Android, он не производит никаких ошибок, но когда я запускаю его в стандартной программе Java, он создает исключение: java.security.InvalidKeyException: недопустимый размер ключа.

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(CHUNK_ENCRYPTION_KEY.getBytes(), 0, 32, "AES");
IvParameterSpec initVector = new IvParameterSpec(AES_INITIALIZATION_VECTOR.getBytes(), 0 , 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, initVector);

CHUNK_ENCRYPTION_KEY - это 32-байтовый ключ, закодированный в программе. AES_INITIALIZATION_VECTOR - это 16-байтовый кодированный вектор инициализации.

Кто-нибудь знает, почему он будет работать на Android, а не на рабочем столе?

Ответы

Ответ 1

При установке JVM для настольных компьютеров по умолчанию (с использованием JRE или JDK от Sun/Oracle) AES ограничивается 128-битным размером ключа. Это остатки законов об импорте/экспорте на криптографическое программное обеспечение. Чтобы разблокировать более крупные размеры ключей AES, вам необходимо загрузить и применить "Файлы политики юрисдикции JCE Unlimited Strength" (см. Внизу на этой странице).

Ограничение размера ключа выполняется кодом внутри класса Cipher. Изменение поставщиков криптографии (например, одному из Bouncy Castle или провайдеров IAIK) не позволит вам обойти это ограничение.

В несвязанной заметке вы не хотите использовать метод raw getBytes() на String, потому что результат зависит от текущей локали (не все используют кодировки UTF-8 или даже ASCII-совместимые). Если вы хотите представить свой ключ как литеральную строку, по крайней мере, используйте явное кодирование, например: CHUNK_ENCRYPTION_KEY.getBytes("UTF-8")

Ответ 2

В README четко не указано, что "JCE Unlimited Strength Jurisdiction Policy Files" следует скопировать в JRK внутри вашего JDK, иначе это не сработает. Путь к файлам должен быть:/path/to/jdk1.7.0_xx/jre/lib/security

Ответ 3

Возможно, у вашего поставляемого вектора KEY и инициализации нет 32 байта, соответственно длина 16 байтов. Вы также можете попытаться использовать конструкторы, которые не принимают параметры смещения и длины ключей:

   SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
   IvParameterSpec ivSpec = new IvParameterSpec(iv);