Статьи

Импорт секретного ключа в хранилище ключей Java методом замены ключа

Если вы программист и имеете дело с проблемами криптографии, вы наверняка слышали о таких ключевых словах, как шифрование, дешифрование и управление ключами. Последнее ключевое слово, управление ключами, определяется как группа операций, таких как генерация, обмен, хранение и защита артефактов безопасности (то есть ключей и сертификатов). Артефакты безопасности являются неотъемлемой частью любых операций шифрования. Без эффективного управления такими ценными ресурсами, система может быть легко взломана злоумышленниками.

Java поддерживает управление ключами, представляя две утилиты;  Java Keys Store  или  JKS  как сокращение и  Java Keytool Utility . Java Key Store — это удобное и безопасное хранилище для ключей и сертификатов. Java хранилище ключей  API  описывает методы и свойство Java KeyStore класса , что делает возможной работу с файлом хранилище ключей программного путем . Для управления ключами и сертификатами Java предоставляет вторую утилиту под названием Java Keytool Utility. Утилита Keytool включена и поставляется с дистрибутивами JDK (Java Development Kit). Руководство по  Keytool представляет и описывает различные команды и опции, которые доступны и предоставляются утилитой Java Keytool. Управление ключами возможно с помощью сервисов, предлагаемых как хранилищем ключей Java, так и утилитой Java Keytool 

Управление ключами, которое обеспечивает Java, охватывает большинство сценариев программирования. К сожалению, есть только одно ограничение. Утилита Java Keytool как основной модуль управления ключами не поддерживает какие-либо средства для импорта пользовательских ключей в хранилище ключей Java. Он поддерживает только генерацию ключей, что приводит к автоматически сгенерированным ключам. Это серьезный недостаток в ситуациях, когда должен происходить обмен ключами между приложениями. В таких ситуациях ключевые спецификации специфичны для моделей безопасности, согласованных между разработчиками. Иногда ключи представляют собой потоки байтов, которые не сопровождаются какими-либо сертификатами. Эти потоки определены как артефакты криптографии и должны быть защищены и сохранены хранилищем ключей Java.

Одним из решений этой проблемы является использование сторонних утилит, таких как  Openssl . Утилита Openssl предлагает механизм, который позволяет взломать недоступность импорта ключей в утилите Java Keytool Хитрость заключается в том, чтобы сохранить ключи в формате PKCS12 с помощью утилиты Openssl и обработать созданный артефакт как новое хранилище ключей. К счастью, утилита Java Keytool поддерживает функцию слияния хранилищ ключей. Созданное хранилище ключей утилитой Openssl затем может быть объединено с любым хранилищем ключей Java утилитой Java Keytool. 

К сожалению, я не смог добиться успеха в следовании этому решению. Одной из причин может быть то, что у моего ключа были настроенные спецификации, такие как размер и стоимость, плюс не было сертификата, который мог бы сопровождать его. Казалось, что не было другого способа преодолеть такое ограничение. Я нашел решение, довольно простое и быстрое, которое помогло мне достичь желаемого результата без зависимости от каких-либо сторонних инструментов. Одним из преимуществ этого метода является использование текущих параметров, предлагаемых утилитами Keytool и Java Keystore. Назовем этот метод « Замена ключа ».

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

keytool -genseckey -alias mykey -keyalg DES -keysize 56 -storetype jceks -keystore <PATH>

Убедитесь, что вы правильно настроили среду выполнения Java. Описание и подробности вышеупомянутой команды и параметров можно найти в руководстве Keytool. После ввода вышеуказанной команды вам будет предложено ввести пароль для хранилища ключей. Если хранилище ключей уже существует, укажите его пароль; в противном случае введите пароль, который будет установлен для вновь созданного хранилища ключей. Если операция прошла успешно, вы можете получить список записей хранилища ключей, выполнив следующую команду:

keytool -list -v -storetype JCEKS -keystore <PATH TO EXISTING KEY STORE>

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

Keystore type: JCEKS

Keystore provider: SunJCE

Your keystore contains 1 entry

Alias name: mykey

Creation date: Sep 30, 2013

Entry type: SecretKeyEntry

Как видите, созданный ключ представлен псевдонимом, который мы установили. Этот ключ автоматически генерируется утилитой Java Keytool. Мы на шаг ближе к тому, что нам нужно. Мы создали ключевую запись с желаемым псевдонимом. Последний шаг — изменить значение ввода ключа на наше индивидуальное значение. Остальные шаги состоят в том, чтобы найти целевую ключевую запись внутри хранилища ключей по ее псевдониму и программно изменить ее значение на наше собственное значение. Следующая простая Java-программа сделает эту работу.

KeyStore ks = KeyStore.getInstance("JCEKS");

  char[] password = "PASSWORD TO KEYSATORE".toCharArray();

  java.io.FileInputStream fis = null;

  try {
 	 ks.load(new FileInputStream("PATH TO KEY STORE"), password);
  } finally {

 	 if (fis != null) {
 		 fis.close();
 	 }
  }

SecretKey mySecretKey = new SecretKeySpec(Util.hex2byte("5A5A5A5A5A5A5A5A"), 0, Util.hex2byte("5A5A5A5A5A5A5A5A").length, "DES");

  KeyStore.SecretKeyEntry skEntry =

  new KeyStore.SecretKeyEntry(mySecretKey);

  ks.setEntry("mykey", skEntry, new KeyStore.PasswordProtection(password));

  java.io.FileOutputStream fos = null;

  try {
	  fos = new java.io.FileOutputStream("PATH TO KEYSTORE");
	  ks.store(fos, password);
  } finally {
	  if (fos != null) {
	 	 fos.close();
 	 }
  }

Эта Java-программа будет:

· Откройте хранилище ключей.

· Загрузите хранилище ключей перед любой операцией.

· Создайте секретный ключ с желаемыми характеристиками (пользовательское значение и пользовательская длина).

· Замените значение целевого ключа, используя метод setEntry () объекта хранилища ключей, указав его псевдоним и новое значение ключа.

· Наконец закройте и сохраните объект хранилища ключей.

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

 try {
 	 ks.load(new FileInputStream("PATH TO KEY SOTRE"), password);
  } finally {
	  if (fis != null) {
		  fis.close();
	  }
  }

  Key key = ks.getKey("mykey ", password);

  System.out.println("-----BEGIN PRIVATE KEY-----");
  System.out.println(new BASE64Encoder().encode(key.getEncoded()));
  System.out.println("-----END PRIVATE KEY-----");

Шаги прямо вперед:

· Загрузить объект хранилища ключей.

Загрузите целевой ключ, используя метод getKey () и указав его псевдоним.

· Получить значение ключа и вывести его значение в формате PEM (кодировка Base 64).

Вуаля! Это наш ключ. 

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

Сэм,