Генерация одного и того же случайного SecretKey дважды - PullRequest
1 голос
/ 05 октября 2009

Мне нужно сгенерировать случайный SecretKey в Java, который я смогу восстановить в будущем. Идея заключается в том, что этот ключ уникален для машины, на которой он создан, и нигде не хранится. Я пытаюсь что-то вроде этого:

KeyGenerator keyGen = KeyGenerator.getInstance("DESede");

String hostname = InetAddress.getLocalHost().getHostName();
SecureRandom random = new SecureRandom(hostname.getBytes());
keyGen.init(random);

secretKey = keyGen.generateKey();

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

Ответы [ 3 ]

3 голосов
/ 05 октября 2009

Вы не можете сгенерировать случайный ключ дважды, потому что он случайный.

Если InetAddress.getLocalHost (). GetHostName () достаточно уникален для вашей цели, вычислите значение хеша и используйте его в качестве ключа. Как сказал Джон, ключ может быть извлечен для любого человека, который знает реализацию.

3 голосов
/ 05 октября 2009

Существует два способа программной защиты ключа:

  • Держите ключ в секрете, или
  • Храните алгоритм в секрете.

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

Если я правильно читаю ваши требования, вам нужен ключ, который

  1. Гарантируется быть уникальным для каждой машины.
  2. Random.
  3. Нигде не хранится.
  4. Воспроизводимый (вашим программным обеспечением).

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

  1. Привязано к хост-машине: ключ с одного компьютера нельзя использовать на другом.
  2. Безопасный: вряд ли будет продублирован, угадан, перепроектирован, и т. Д. .
  3. Безопасный: вряд ли будет обнаружен в вашей программе.
  4. Воспроизводимый: ваше приложение должно быть способно восстановить ключ при необходимости.

Все эти новые требования, за исключением # 3, могут быть удовлетворены с помощью этой процедуры:


  1. Генерирует секретный случайный набор seed , который будет использоваться на каждой машине.
  2. Выберите машинно-зависимую подпись , уникальную для каждого хоста, и добавьте ее в начальное число. Классическим примером является MAC-адрес, но на машинах с двумя или более сетевыми картами вы должны быть осторожны, чтобы каждый раз использовать один и тот же сетевой адаптер!
  3. Хэш результат с помощью алгоритма (например, SHA ), который будет генерировать результат, который является достаточно уникальным и необратимым.

Теперь все, что осталось, - это выполнить третье требование, сделав так, что злоумышленнику будет довольно трудно угадать один секретный предмет: семя. И именно здесь процесс становится скорее религиозным аргументом, чем техническим, потому что «достаточно сложный» зависит от того, насколько сильно злоумышленник хочет найти ключ и риски, если он / она преуспеет.

Чтобы обеспечить максимальную безопасность, ключ должен храниться вне вашего приложения, например, , в вашем мозгу и предоставляться каждый раз, когда это необходимо. Но в целом приемлема некоторая форма более слабой защиты через механизм мрака ; один из моих любимых - использовать что-то вроде 0x%-6.2d, которое, скорее всего, будет пропущено как формат printf(). Если вы параноик, храните его по частям и воссоздайте в той части приложения, которая иначе не связана с модулями обработки ключей.

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

Удачи!

3 голосов
/ 05 октября 2009

Даже если бы он сработал для вас , у вас не было бы "секретного" ключа - у вас был бы ключ, который полностью выводится из имени хоста. Это не секрет - все используют свое имя в качестве пароля. Любой, кто захочет атаковать зашифрованные данные, должен просто знать имя машины, на которой был создан ключ, и тогда у него будет доступ.

Окончательная форма ключа не так важна, как информация, необходимая для ее воссоздания. Чтобы ключ был эффективным, эта информация должна быть в основном секретной.

...