2009-10-05 4 views
1

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

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

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

secretKey = keyGen.generateKey(); 

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

+1

Что вы пытаетесь сделать? Для чего нужен ключ? Можете ли вы немного объяснить всю свою среду? вероятно, лучший способ решить проблему. –

ответ

3

Есть два способа крепят ключа программно:

  • Держите ключ сам секрет, или
  • Стараться алгоритм секрет.

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

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

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

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

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

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


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

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

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

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

Удачи вам!

+0

Большое спасибо, это похоже на информацию, которая мне нужна. Пожалуйста, будьте уверены, я знаю, что то, что я делаю, легко компрометировать, но меня попросили найти способ защитить пароль, используемый для защиты доступа к остальным нашим ключам, причем требование заключается в том, что он не должен быть «тривиально» открываемым, т. е. не должно случайно случайно наткнуться на пароль в текстовой форме. – AndyB

+0

Затем вы ищете KeyStore. (каламбур не предназначен) –

3

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

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

+0

Но он может использовать соль, чтобы сделать ее частной? Или это не хорошая идея? – codevour

+0

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

3

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

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