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);