- Основы Java Keytool: работа с Java Keystore
- Создание и импортирование записей
- Создание ключей
- Создание CSR для существующего закрытого ключа
- Импортирование подписанного/Root/промежуточного сертификата
- Создание самоподписанного сертификата в новом/существующем хранилище
- Просмотр записей хранилища ключей
- Проверка контрольной суммы сертификата
- Подробное содержание хранилища
- Использование Keytool для просмотра информации о сертификате
- Экспортирование сертификатов
- Редактирование хранилища ключей
- Изменение пароля хранилища
- Удаление псевдонима
- Изменение псевдонима
- Итоги
- Хранилище ключей и сертификатов
- Утилита keytool
- Создание самоподписанного сертификата
- Distinquished Name
- Создание пары ключей
- Опции команды genkeypair
- Экспорт сертификата
- Импорт сертификата
- Экспорт сертификата из хранилища cacerts
- Импорт сертификата в хранилище
- Просмотр хранилища
- Опции команды list
- Пример просмотра хранилища и сертификата
- Листинг примера
- Скачать пример
Основы Java Keytool: работа с Java Keystore
Java Keytool – это инструмент Java для управления ключами, сертификатами и хранилищами ключей. Java Keystore (или JKS) – это хранилище сертификатов открытых ключей и авторизации, которое часто используется приложениями на основе Java для шифрования, аутентификации и установки соединений HTTPS. Все его записи защищены паролем хранилища ключей. Запись хранилища ключей идентифицируется псевдонимом и содержит надежные ключи и сертификаты.
Данное руководство описывает использование команд keytool, очень полезных при работе с JKS. Также оно охватывает создание и редактирование хранилищ ключей Java для Java-приложений.
Создание и импортирование записей
Данный раздел посвящен командам Java Keytool, которые создают пары ключей и сертификатов, а также импортируют сертификаты.
Создание ключей
Используйте этот метод для поддержки HTTPS (HTTP по TLS). В данном разделе показано, как создать новую пару ключей в новом или уже существующем хранилище ключей Java, которые могут быть использованы для создания запроса на подпись сертификата (CSR) или получения SSL-сертификата в центре сертификации.
Данная команда сгенерирует пару 2048-битных RSA-ключей под указанным псевдонимом (в данном случае это domain) в указанном файле хранилища (keystore.jks).
keytool -genkeypair \
-alias domain \
-keyalg RSA \
-keystore keystore.jks
Если же заданного хранилища ключей не существует, оно будет создано после получения запрашиваемой информации (а именно пароля хранилища ключей, строки Distinguished Name (для закрытого ключа) и пароля закрытого ключа).
Создание CSR для существующего закрытого ключа
Чтобы сгенерировать запрос на подпись сертификата, который можно отправить в ЦС для получения надежного SSL-сертификата, следуйте данному разделу руководства. Для этого понадобятся уже существующее хранилище ключей и псевдоним.
Данная команда создаст CSR (domain.csr), подписанный закрытым ключом с псевдонимом domain в хранилище keystore.jks:
keytool -certreq \
-alias domain \
-file domain.csr \
-keystore keystore.jks
Введите пароль хранилища ключей, после чего запрос будет создан.
Импортирование подписанного/Root/промежуточного сертификата
В данном разделе показано, как импортировать сертификаты (например, подписанный ЦС сертификат) в хранилище ключей. Он должен соответствовать закрытому ключу с определенным псевдонимом. Также данную команду можно использовать для импортирования root или промежуточного сертификата, который может потребовать ЦС для завершения доверительной цепочки. Просто укажите уникальный псевдоним, (например, root вместо domain) и сертификат, который необходимо импортировать.
Следующая команда импортирует сертификат (domain.crt) в хранилище ключей (keystore.jks) под указанным псевдонимом (domain). Подписанный сертификат при импортировании должен соответствовать закрытому ключу с указанным псевдонимом:
keytool -importcert \
-trustcacerts -file domain.crt \
-alias domain \
-keystore keystore.jks
На данном этапе будет предложено ввести пароль хранилища ключей, а затем подтвердить импортирование.
Примечание: можно также использовать эту команду, чтобы импортировать сертификаты ЦС в Java truststore (хранилище доверенных сертификатов), которое, как правило, находится в $JAVA_HOME/jre/lib/security/cacerts, (предполагается, что JRE или JDK установлены в $JAVA_HOME).
Создание самоподписанного сертификата в новом/существующем хранилище
В данном разделе показано, как создать самоподписанный сертификат для приложения Java. На самом деле, для этого используется та же команда, что и для создания новой пары ключей, но с параметром days, задающим срок действия сертификата.
Итак, данная команда создаст пару 2048-битных RSA-ключей, действительных на протяжении 365 дней, с указанным псевдонимом (domain) в заданном файле ключей (keystore.jks):
keytool -genkey \
-alias domain \
-keyalg RSA \
-validity 365 \
-keystore keystore.jks
Если заданного хранилища ключей не существует, команда создаст его, получив необходимые данные (это пароль хранилища, Distinguished Name (дл закрытого ключа) и пароль закрытого ключа).
Просмотр записей хранилища ключей
В данном разделе речь пойдет о содержимом Java Keystore, а именно о просмотре информации сертификата и экспортировании сертификатов.
Проверка контрольной суммы сертификата
Данная команда выводит список контрольных сумм всех сертификатов хранилища (keystore.jks) с соответствующими псевдонимами.
keytool -list \
-keystore keystore.jks
При этом будет запрошен пароль хранилища. Кроме того, можно ограничить вывод до определенного псевдонима с помощью опции -alias domain (где domain – нужный псевдоним).
Подробное содержание хранилища
Данная команда выведет подробную информацию о записях, находящихся в хранилище keystore.jks, в том числе длину цепи сертификата, контрольных сумм сертификатов в цепочке, имена (distinguished name), серийные номера, а также дату создания и срок дейтвия по псевдонимам:
keytool -list -v \
-keystore keystore.jks
На данном этапе нужно ввести пароль хранилища ключей. Опять же, с помощью опции -alias domain (где domain – это псевдоним) можно ограничить вывод до определенного псевдонима.
Примечание: также эту команду можно использовать, чтобы просмотреть сертификаты в хранилище доверенных сертификатов Java (как правило, оно находится в $JAVA_HOME/jre/lib/security/cacerts, если JRE или JDK установлены в $JAVA_HOME).
Использование Keytool для просмотра информации о сертификате
Данная команда выведет подробную информацию о файле сертификата (certificate.crt), в том числе контрольную сумму, distinguished name владельца и срок его действия:
keytool -printcert \
-file domain.crt
При этом нужно ввести пароль хранилища.
Экспортирование сертификатов
Данная команда экспортирует бинарный DER-зашифрованный сертификат (domain.der) с псевдонимом (domain) в хранилище (keystore.jks):
keytool -exportcert
-alias domain
-file domain.der
-keystore keystore.jks
Укажите пароль хранилища ключей.
Редактирование хранилища ключей
Данный раздел охватывает редактирование записей Java Keystore (например, удаление и изменение псевдонимов).
Изменение пароля хранилища
При помощи этой команды можно изменить пароль хранилища (keystore.jks):
keytool -storepasswd \
-keystore keystore.jks
Укажите текущий пароль хранилища ключей, а затем новый пароль. Задать новый пароль можно и при помощи самой команды, внеся в нее опцию -new newpass, где newpass – новый пароль.
Удаление псевдонима
Данная команда удалит псевдоним domain из хранилища keystore.jks:
keytool -delete \
-alias domain \
-keystore keystore.jks
Укажите пароль хранилища.
Изменение псевдонима
При помощи данной команды можно изменить псевдоним (например, domain на newdomain):
keytool -changealias \
-alias domain \
-destalias newdomain \
-keystore keystore.jks
Итоги
Данное руководство описывает большинство операций, которые выполняются при управлении Java Keystores. Конечно, охватить все функции в одной статье невозможно. Но зная базовые команды, можно самостоятельно поэкспериментировать с управлением хранилищами.
Данное руководство основано на версии хранилища ключей, которое поставляется с Java 1.7.0. чтобы установить Java, читайте данную статью.
Хранилище ключей и сертификатов
Защита данных в приложениях имеет важное значение, защита конфиденциальной информации — первостепенное. Одним из самых распространённых способов защиты информации во все времена является шифрование данных. Криптография, симметричное и асимметричное шифрование, ключи и сертификаты непосредственно связаны с данной задачей. Используемые для защиты информации ключи и сертификаты также нужно надежно защитить. Для этих целей используется keystore — хранилище сертификатов и ключей.
keystore — это специализированное хранилище секретных данных, которое используется Java-приложениями для шифрования, аутентификации и установки HTTPS соединений. Так, для аутентификации клиента и сервера, устанавливающих SSL (Secure Sockets Layer — уровень защищённых cокетов) соединение, требуются приватные ключи и сертификаты. Если используется односторонняя аутентификация, то keystore используется только на серверной стороне. При двусторонней аутентификации клиент и сервер обмениваются сертификатами; соответственно и у сервера, и у клиента должны быть keystore с парой ключей private/public + сертификат. Иными словами keystore используется для хранения ключей и сертификатов, применяемых для идентификации владельца ключа (клиента или сервера).
Java поддерживает несколько форматов хранилищ keystore :
• jks | — стандартный тип хранилища в виде файла с расширением jks («java key storage»); устанавливается по умолчанию и, поэтому, применяется наиболее часто. |
• jceks | — альтернативная реализация хранилища, которая использует более сильное шифрование на основе triple DES; можно обновить имеющееся jks-хранилище до jceks соответствующей командой утилиты keytool. |
• pkcs12 | — тип хранилища, предназначенный прежде всего для хранения или переноса закрытых ключей пользователя, сертификатов и пр. |
Каждая запись в keystore имеет уникальный псевдоним (alias). Рекомендуется в keystore не использовать alias’ы, отличающиеся только регистром. В стандартной реализации каждый ключ в хранилище защищается паролем; кроме того, всё хранилище целиком может быть защищено отдельным паролем.
Стандартное хранилище доверенных CA-сертификатов (Certificate Authority) для Java приложений располагается в директории jre/lib/security/cacerts (пароль — changeit).
Информацию в хранилище можно разделить на две категории: ключевые записи (пары ключей private/public) и доверенные сертификаты. Ключевая запись, используемая для криптографических целей, включает идентификационные данные объекта и его закрытый ключ. Доверенный сертификат содержит идентификационные данные объекта и открытый ключ. Запись с доверенным сертификатом не может использоваться в тех случаях, где требуется закрытый ключ.
Чтобы отделить ключевые записи от сертификатов целесообразно использовать различные хранилища : один для собственных ключей, а другой — для доверенных сертификатов, включая сертификаты Центров сертификации (CA). Такой подход позволит реализовать разделение между собственными сертификатами и соответствующими закрытыми ключами, и доверенными сертификатами. Дополнительно можно обеспечить более высокую защиту для закрытых ключей в отдельном keystore с ограниченным доступом, а доверенные сертификаты оставить в более свободном доступе.
В конце статьи представлен Java пример просмотра содерживого хранилища ключей и сертификатов CertificateReader.
Утилита keytool
Для управления парами ключей (private/public), сертификатами и хранилищем keystore Java включает утилиту keytool, располагаемую в директории bin. Для запуска keytool можно использовать командную строку. Опции утилиты позволяют выполнять различные операции и получать определенные сведения. Так, чтобы получить информацию об утилите, можно просто выполнить команду keytool без опций :
Чтобы получить дополнительную справку о команде необходимо указать ее наименование и волшебное слово help. Не забывайте о дефисе ‘-‘ перед опциями :
Создание самоподписанного сертификата
Для создания самоподписанного сертификата также необходимо использовать команду -genkey с указанием срока действия сертификата в опции -validity. Следующая команда создаст пару 2048-битных RSA-ключей, действительных на протяжении 365 дней, с указанным псевдонимом (parent) в заданном файле/хранилище ключей (keystore.jks). Закрытый ключ в хранилище «закрывается» паролем, открытый ключ «оборачивается» в самоподписанный сертификат .
Если заданного хранилища ключей (keystore.jks) не существует, то keytool создаст его. При выполнении команды keytool будет запрашивать некоторые необходимые данные : пароль хранилища, Distinguished Name и пароль закрытого ключа. Многие параметры используются со значениями по умолчанию. Так, например, алиас — mykey, хранилище — .keystore в домашней директории пользователя (HOMEPATH), алгоритм шифрвания — SHA1withDSA и пр.
Distinquished Name
Сертификат создается в формате X.509. В этом формате в качестве идентификатора владельца используется Distinquished Name или просто DN в формате X.500. Этот же формат идентификации объектов используется в LDAP-протоколе или в SNMP. Distinquished Name задается в виде разделенных через запятую атрибутов :
- CN — common name (имя владельца);
- OU — organizational unit or department/division (департамент/отдел);
- O — organization name (наименование организации);
- L — locality or city (город/местоположение);
- ST — state or province;
- C — country, two chars (страна).
Часть из атрибутов могут быть пропущены; в этом случае им будет присвоено значение Unknown.
Одним из важных атрибутов сертификата являются альтернативные имена SAN (SubjectAlternativeName). Подробности и пример внесения SAN в самоподписанный сертификат представлены на странице настройки конфигурации сервера Tomcat.
Параметры сертификата можно указывать в качестве опции команды. Так, в следующем варианте примера задаётся информация о компании, наименование алиаса, тип и размещение хранилища, срок действия, алгоритм для генерации ключей, размер ключа, пароли на хранилище и на ключ.
Новое хранилище было размещено в той же директории, где и располагается keytool.
Создание пары ключей
Для создания пары ключей необходимо использовать команду «-genkeypair». Следующая команда создаст пару ключей «keypair» в хранилище keystore.jks, где размещен созданный ранее сертификат.
Сертификат и закрытый ключ сохранены в виде новой keystore записи, идентифицированной псевдонимом «keypair». Открытый ключ обертывается в формат X.509 — это самоподписанный сертификат, который сохранен как одноэлементная цепочка сертификата.
Опции команды genkeypair
- [-storepass storepass]
- [-keypass keypass] — является паролем, используемым для защиты закрытого ключа
- [-dname dname] — определяет отличительное имя в формате X.500, связанное с псевдонимом и используемое в качестве issuer и subject поля в самоподписанном сертификате
- <-keyalg keyalg>— определяет алгоритм, который будет использоваться, чтобы генерировать пару ключей
- <-keysize keysize>— определяет размер каждого ключа, который будет сгенерирован
- <-sigalg sigalg>— определяет алгоритм, который должен использоваться, чтобы подписать самоподписанный сертификат; алгоритм должен быть совместимым с keyalg
- <-ext ext>*
- <-providerClass provider_class_name <-providerArg provider_arg>>
Создадим еще две пары ключей с псевдонимами «keypair1» и «keypair2», чтобы при просмотре содержимого хранилища (ниже) был небольшой список пар ключей :
Экспорт сертификата
Сертификат можно экспортировать из хранилища и предоставить его пользователям Вашей «подписанной» программы. Тогда пользователи могут занести Ваш сертификат в свое хранилище доверенных сертификатов. Для экспорта сертификата используется команда «exportcert». Следующий пример извлекает из хранилища сертификат в файл «parent.cer» :
Импорт сертификата
Чтобы импортировать сертификат в хранилище, нужно его сначала получить каким-либо образом. Не будем мудрить и извлечем сертификат с псевдонимом veriSignclass1g3ca из хранилища доверенных сертификатов jre\lib\security\cacerts (пароль хранилища changeit). То есть выполним команду экспорта сертификата с указанием соответствующего хранилища :
Экспорт сертификата из хранилища cacerts
Импорт сертификата в хранилище
Чтобы импортировать сертификат в хранилище keystore.jks необходимо использовать команду «importcert». Если в качестве опции указать «-trustcacerts», то сертификат импортируется в хранилище доверенных сертификатов, т.е. в jre\lib\security\cacerts. При выполнении команды импорта утилита keytool попросит ввести пароль хранилища :
Просмотр хранилища
Для чтения содержимого хранилища необходимо использовать команду «-list». В качестве опции «-keystore» можно указать путь к хранилищу. По умолчанию команда «-list» отображает цифровой отпечаток SHA1 сертификата. Следующий код позволяет просмотреть содержимое созданного хранилища, включающего сертификат и три пары ключей :
Опции команды list
Если при просмотре хранилища использовать опцию «-v», то информация о сертификате выводится с дополнительной информацией, включающей владельца, порядковый номер и т.д. При использовании опции «-rfc» содержание сертификата печатается согласно интернет-стандарта RFC-1421.
На странице описания SSL сертификата представлен результат выполнения команды просмотра хранилища keytool -list для опций ‘-v’ и ‘-rfc’.
Полную англоязычную версию документации на keytool можно найти здесь.
Пример просмотра хранилища и сертификата
На скриншоте представлен пример CertificateReader, позволяющий просматривать хранилище ключей и сертификаты, а также извлекать информацию о сертификате.
Внутри сертификата хранится пара значений Distinqueshed Names. Один DN принадлежит владельцу сертификата, а второй DN указывает идентификатор цента сертификации (CA), подписавшего сертификат. В случае с самоподписанным (self-signed) сертификатом, оба эти DN указывают на владельца сертификата.
Листинг примера
Интерфейс примера выполнен с использованием библиотеки Swing. Поскольку Swing не является предметом данной статьи, то методы формирования интерфейса не представлены в листинге примера. При необходимости желающие могут скачать исходный код примера в конце страницы.
В листинге примера представлены два метода : loadKeyStore, showCertificate. Первый метод позволяет выбрать хранилище сертификатов. Второй метод выполняет чтение сертификата и представление его параметров в интерфейсе. После листинга представлен скриншот, на котором выполнено чтение созданного сертификата.
Примечание : класс CertificateReader используется в качестве примера на странице цифровой подписи jar файлов
Скачать пример
Рассмотренный на странице пример просмотра хранилища ключей и сертификатов можно скачать здесь (2.5 Кб).