2013-11-25 4 views
0

Я нашел это в интернете: http://www.code2learn.com/2011/06/encryption-and-decryption-of-data-using.htmlГенерация ключа для AES

поясню, что я хочу сделать, это вместо того, чтобы ключевой набор как

new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' }; 

Я хочу, чтобы это было случайным (но должен быть 16 байт) и иметь доступ к нему (распечатать его на экране). Кроме того, есть ли способ установить его как строку, а не типа байта?

+0

Вы можете получить массив байтов из строки, используя: «TheBestSecretKey» .getBytes («UTF-8»); вы можете создать случайную последовательность строк и получить байты одинаково. Проверьте ответ http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string – Cratylus

+0

Я хочу получить строку из последовательности байтов, а не байта из строки. На самом деле я хочу, чтобы пользователь вводил ключ вместо того, чтобы быть IV (вектор инициализации). –

+1

Это ужасный пример. Он будет использовать ECB, и он сбивает пароли с ключами. Не может быть намного хуже в нескольких строках. –

ответ

4

сильный ключ AES будет 16, 24 или 32 байт долго. Если вы ограничиваете ключ байтами, которые отображаются на печатные символы US-ASCII, ключ будет слабее, чем ожидалось, потому что его диапазон ограничен (примерно до 100 бит, а не 128 — в миллионы раз слабее). Было бы лучше использовать кодировку, такую ​​как шестнадцатеричная, base-64 или base-85 для представления ключа как текста; конечно, эти представления будут длиннее.

Чтобы создать защищенный ключ, используйте KeyGenerator, который основан на правильно сформированном генераторе криптографических случайных чисел; провайдеры будут выбирать свой собственный ГСЧ, если вы не указали один:

KeyGenerator gen = KeyGenerator.getInstance("AES"); 
gen.init(128); /* 128-bit AES */ 
SecretKey secret = gen.generateKey(); 
byte[] binary = secret.getEncoded(); 
String text = String.format("%032X", new BigInteger(+1, binary)); 
System.out.println(text); 

Если вы хотите, вы можете создать экземпляр своего собственный SecureRandom экземпляра, используя свой предпочтительный алгоритм и поставщик, и передать его в генератор ключей через перегрузку метода init().

Существуют ключевые методы деривации, которые пытаются смягчить слабые стороны основанных на пароле ключей, но ключ на основе пароля всегда будет более предсказуемым.

+0

Он печатает что-то вроде C78857B2C06293AABAA3332A1A80A684 , который должен иметь длину 16 символов. Почему у него двойной? Кроме того, что, если я хочу сделать 192-битный ключ длиной 24 символа? Очевидно, я меняю gen.init (192), но он будет содержать 48 символов. –

+1

@ user2995645 Потому что это шестнадцатеричная кодировка. Это 16 байт. Вы прочитали мой ответ? Не ставить на него слишком тонкую точку, но ключи - двоичные, * строка бит, * не текст, * строка символов. 192-битным ключом будет 48 шестнадцатеричных символов, 32 символа в базе-64 или 30 символов в базе-85. Если вы используете только печатные символы, 16-символьный ключ всего 105 бит, 24-символьная клавиша - всего 158 бит. – erickson

1

Основном, что я хочу сделать, это вместо того, чтобы ключевой набор как


new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' }; 

Хорошо, потому что это страшно и небезопасно. Это худший секретный ключ. Пароли не являются ключами и не должны использоваться как таковые.

Я хочу, чтобы это было случайным (но должно быть 16 байт)

Вы хотите, чтобы это было безопасно случайно:

public static void main(final String ... args) throws Exception { 
    final SecureRandom prng = new SecureRandom(); 
    final byte[] aes128KeyData = new byte[128/Byte.SIZE]; 
    prng.nextBytes(aes128KeyData); 
    final SecretKey aesKey = new SecretKeySpec(aes128KeyData, "AES"); 
    System.out.println(toHex(aesKey.getEncoded())); 
} 

private static String toHex(final byte[] data) { 
    final StringBuilder sb = new StringBuilder(data.length * 2); 
    for (final byte b : data) { 
     sb.append(String.format("%02X", b)); 
    } 
    return sb.toString(); 
} 

и иметь к нему доступ (печать это на экране).

См. Выше.

Кроме того, есть ли способ установить его как строку вместо байтового типа?

Ну, да, вы можете декодировать вышеупомянутую шестнадцатеричную строку. Но в итоге алгоритм AES требует двоичного ключа, двоичного открытого текста и генерирует двоичный вывод. Класс SecretKey - это немного больше, чем обертка вокруг массива байтов.

Чтобы сделать больше конверсий и из строк, узнать о и ...

Смежные вопросы