Получение исключения java.security.InvalidKeyException: неверная длина ключа AES: 28 байт

Я использую следующую команду unix для создания 128-битного секретного ключа для AES и записи его в файл.

dd if=/dev/urandom of=/data/key.txt bs=16 count=1

Я читаю ключ из файла в классе Java и использую его для шифрования/дешифрования.

BufferedReader reader = new BufferedReader(new FileReader(keylocation.getFile()));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
  stringBuilder.append(line);
}
String secretKey = stringBuilder.toString();
SecretKeySpec key = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
encryptedString = (Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));

Но я получаю следующее исключение

java.security.InvalidKeyException: Invalid AES key length: 28 bytes

Поскольку я генерирую 128-битный (16 байт) ключ в файле, как его изменить на 28 байт?


person user3244519    schedule 25.02.2014    source источник


Ответы (2)


Вы используете Reader. Цель Reader — читать текст.

Но вам нужен двоичный файл, т.е. массив байтов.

Решение: не используйте Reader. Используйте InputStream и читайте в 16-элементный массив byte.

person fge    schedule 25.02.2014
comment
+1, я думаю, что всегда хэш MD5 для выбранного ключа также обеспечит 128 бит - person StoopidDonut; 25.02.2014
comment
@PopoFibo Если ваш ключ представляет собой строку, то это должен быть либо двоичный ключ, закодированный с использованием шестнадцатеричных чисел, либо основание 64 правильного размера. В противном случае он должен обрабатываться как пароль. Пароли должны быть преобразованы в ключи с использованием функции получения ключа на основе пароля, такой как PKCS#5/PBKDF2, а не только MD5. - person Maarten Bodewes; 26.02.2014
comment
@owlstead имеет смысл, я просто думал о размере ключа, хотя - person StoopidDonut; 26.02.2014

urandom генерирует блок байтов, содержащих непечатаемые символы. Использование буферизованного считывателя и чтение как Java UTF-8 может вызвать проблемы, вероятно, из-за получения некоторых байтов в качестве управляющих символов и создания большего количества данных из-за преобразований кодирования.

Использование InputStream должно решить проблему получения байтов вместо строки, или вы должны попытаться создать читаемый ключ, используя другую команду, например:

tr -dc A-Za-z0-9_ < /dev/urandom | head -c 16 > /data/key.txt
person Dubas    schedule 25.02.2014