Что такое keystore и truststore
Keystore в Java
Что такое Java Keystore?
Keystore используется для хранения собственных приватных ключей и сертификатов сервера или клиента.
Для аутентификации клиента и сервера устанавливающих SSL соединение требуются приватные ключи и сертификаты. Если используется односторонняя аутентификация, то keystore нужен только на серверной стороне. При двусторонней аутентификации и клиент и сервер обмениваются сертификатами, соответственно и у сервера, и у клиента должен быть keystore с парой приватный ключ/публичный ключ + сертификат.
Т.е. иными словами Keystore используется для хранения ключей и сертификатов, использующихся для идентификации владельца ключа (клиента или сервера).
Trust Store
Второй тип keystore применяется для хранения trusted сертификатов. В него кладутся ключи trusted certificate authorities CA. При пользовании самоподписанными сертификатами, в trusted store может класться самоподписанный сертификат. Это тоже keystore, но в Java он называется trusted store.
Форматы Keystore поддерживаемые Java
Т.о., как описано выше, keystore — контейнер, используемый для хранения ключей и сертификатов. Java поддерживает два формата keystore:
Тип keystore, используемый по-умолчанию, задается в Java security properties файле свойством keystore.type. Если приложение обращается к key store файлу без явного указания его типа, используется JKS формат. Java security properties файл расположен в каталоге lib внутри инсталляционного директория с Java по пути: /lib/security/java.security
Для работы с keystore в java дистрибутиве есть специальная утилита keytool. Keytool вполне достаточно для операций с ключами в Java. Однако JKS формат является пропиетарным и закрытым. Поэтому часто для разнообразных конвертаций и взаимодействия со сторонними разработчиками могут использоваться утилиты, поставляемые в комплекте с библиотекой OpenSSL.
В тех случаях, когда планируется использовать ключи исключительно в Java keystore в формате JKS вполне подойдет.
Алиасы
Keystore (по крайней мере в JKS формате), позволяет хранить несколько пар ключей и сертификатов. Для идентификации каждой пары или отдельного сертификата используется алиас. Алиас указывается в исходном коде при доступе к соответствующему ключу или сертификату. Доступ к каждому алиасу ограничивается паролем.
Создание keystore
Процесс генерации keystore (JKS или PKS12) включает генерацию пары ключей (приватного и публичного). Затем получение от Certificate Authority (CA) подписи к публичному ключу и связанной с ним идентифицирующей информации в виде сертификата. Certificate authority генерирует сертификат на основе публичного ключа и идентификационной информации, переданной ему в виде CSR.
Wikipedia говорит, что CA выдает сертификат, привязывающий публичный ключ к указанному Distinguished Name (это может быть имя хоста (hostname, имя пользователя или название приложения). Шаги по созданию keystore представляющего пользователя, приложение или хост следующие:
В java при генерации пары ключей с помощью keytool сразу создается самоподписанный self-signed сертификат, который можно немедленно использовать для тестирования. Следующие шаги, таким образом, нужны только для создания полноценного официального сертификата.
Сгенерировать запрос на получение сертификата (Certificate Signing Request (CSR)).
Получить CSR, подписанный доверенным CA (output of this is a certificate)
Импортировать сертификат, сделанный CA в ваш key store.
Импортировать сертификат CA в ваш truststore как trusted certificate
Java’s Default Keystore
Java’s Default Truststore
Приложение может указать Java использовать определенный truststore файл установкой свойства javax.net.ssl.trustStore. Если приложение не указывает явно truststore, тогда truststore по-умолчанию загружается и используется. По-умолчанию java truststore находится в /lib/security/cacerts и его пароль по-умолчанию: ‘changeit’. Файлы truststore — обычные keystore файлы, содержащие один или более сертификатов trusted CA (Certificate Authorities).
Keytool
Для облегчения создания и управления keystore файлами в дистрибутив Java входит утилита keytool, позволяющая создавать JKS файлы. Keytool позволяет управление сертификатами и парами публичных приватных ключей.
Сертификат создается в формате X.509. В этом формате в качестве идентификатора владельца используется Distinquished Name или просто DN в формате X.500. Точно такой же формат идентификации объектов используется, например в LDAP-протоколе или в SNMP. Distinquished Name задается в виде разделенных через запятую атрибутов: «CN=Andrey Chesnokov, OU=dev64, O=dev64-wordpress, L=Unknown, ST=Unknown, C=RU». Здесь отдельные атрибуты расшифровываются так:
Часть из атрибутов могут быть пропущены, в данном случае им присвоено значение Unknown. При генерации тестового keystore, значения можно присваивать любые. При получении официального сертификата, данные регламентируются и проверяются Certificate Authority организацией.
Внутри каждого сертификата в формате X.509 хранится пара Distinqueshed Names (DN), один DN принадлежит владельцу сертификата, а второй DN указывает идентификатор CA, подписавшей сертификат. В случае с self-signed сертификатом, оба эти DN указывают на владельца сертификата.
Т.о. с помощью одной команды получается keystore с парой ключей и сертификатом, остается этот keystore взять и подложить в нужный каталог к своей программе. Но это уже другая история.
Обязательно стоит почитать официальную документацию на keytool, она содержит много полезного.
Некоторые команды для работы с сертификатами:
Криптография в Java. Класс KeyStore
Привет, Хабр! Представляю вашему вниманию перевод 9 статьи «Java KeyStore» автора Jakob Jenkov из серии статей для начинающих, желающих освоить основы криптографии в Java.
Оглавление:
Хранилище ключей
Java KeyStore — это хранилище ключей в виде базы данных, представленное классом KeyStore (java.security.KeyStore). Хранилище можно записать на диск и снова прочитать, оно может быть защищено паролем, а каждая запись ключа в хранилище ключей может быть защищена собственным паролем, что делает класс KeyStore полезным механизмом для безопасной работы с ключами шифрования. Хранилище ключей может содержать ключи следующих типов:
Закрытый и открытый ключи используются в асимметричном шифровании. Открытый ключ может иметь связанный сертификат. Сертификат — это документ, удостоверяющий личность человека, организации или устройства, претендующего на владение открытым ключом. Сертификат обычно имеет цифровую подпись проверяющей стороны в качестве доказательства. Секретные ключи используются в симметричном шифровании. В большинстве случаев при настройке безопасного соединения симметричные ключи уступают асимметричным, поэтому чаще всего вы будете хранить открытые и закрытые ключи в хранилище ключей.
Создание хранилища ключей
Загрузка хранилища ключей
Прежде чем использовать экземпляр хранилища ключей, его необходимо загрузить. Экземпляры класса KeyStore часто записываются на диск или в другое хранилище для последующего использования, потому класс KeyStore предполагает, что вы должны прочитать его данные, прежде чем сможете его использовать. Однако можно инициализировать пустой экземпляр KeyStore без данных, как вы увидите позже.
Загрузка данных из файла или другого хранилища выполняется путем вызова метода load() который принимает два параметра:
Вот пример загрузки хранилища ключей:
Получение ключей
После приведения к KeyStore.PrivateKeyEntry вы можете получить доступ к закрытому ключу, сертификату и цепочке сертификатов с помощью следующих методов:
Помещение ключей в хранилище
Хранение
Мне было интересно понять, как / когда вы различаете магазины при использовании keytool.
Итак, я создал хранилище ключей, используя
который создает мой файл keystore.ks. Я отвечаю yes на вопрос, доверяю ли я Бобу, но мне неясно, создал ли он файл хранилища ключей или файл хранилища доверенных сертификатов? Я могу настроить свое приложение для использования файла как либо.
и с помощью System.setProperty( «javax.net.debug», «ssl») set я могу видеть сертификат в доверенных сертификатах (но не в разделе хранилища ключей). Конкретный сертификат, который я импортирую, имеет только открытый ключ, и я собираюсь использовать его для отправки Бобу через SSL-соединение (но, возможно, лучше оставить его для другого вопроса!)
Любые указатели или разъяснения будут высоко ценится. Является ли вывод keytool одним и тем же независимо от того, что вы импортируете, и это просто соглашение, которое гласит, что одно является хранилищем ключей, а другое хранилищем доверия? Какая связь при использовании SSL и т. Д.?
Разница между KeyManager и TrustManager (и, следовательно, между javax.net.ssl.keyStore и javax.net.ssl.trustStore ) заключается в следующем (цитируется в справочном руководстве JSSE ):
TrustManager: определяет, следует ли доверять учетным данным удаленной аутентификации (и, следовательно, соединению).
KeyManager: определяет, какие учетные данные для аутентификации отправлять на удаленный хост.
Мне было интересно понять, как и когда вы различаете магазины при использовании keytool.
Итак, я создал хранилище ключей, используя
Который создает мой файл keystore.ks. Я отвечаю yes на вопрос, доверяю ли я Бобу, но мне неясно, создал ли это файл хранилища ключей или файл хранилища доверенных сертификатов? Я могу настроить свое приложение на использование файла в любом из них.
И с установленным System.setProperty( «javax.net.debug», «ssl») я могу видеть сертификат в списке доверенных сертификатов (но не в разделе хранилища ключей). В конкретном сертификате, который я импортирую, есть только открытый ключ, и я намерен использовать его для отправки материалов Бобу через SSL-соединение (но, возможно, это лучше оставить для другого вопроса!).
6 ответов
Разница между KeyManager и TrustManager (и, следовательно, между javax.net.ssl.keyStore и javax.net.ssl.trustStore ) заключается в следующем (цитата из Справочное руководство JSSE):
TrustManager: определяет, следует ли доверять учетным данным удаленной аутентификации (и, следовательно, соединению).
KeyManager: определяет, какие учетные данные для аутентификации отправлять на удаленный хост.
(Доступны и другие параметры, и их значения по умолчанию описаны в Справочное руководство JSSE. Обратите внимание, что, хотя для хранилища доверенных сертификатов есть значение по умолчанию, для хранилища ключей его нет.)
По сути, хранилище ключей в javax.net.ssl.keyStore предназначено для хранения ваших личных ключей и сертификатов, тогда как javax.net.ssl.trustStore предназначено для хранения сертификатов ЦС, которым вы готовы доверять, когда удаленная сторона представляет свой сертификат. В некоторых случаях это может быть одно и то же хранилище, хотя часто лучше использовать разные хранилища (особенно когда они основаны на файлах).
Хранилище ключей просто хранит закрытые ключи, тогда как хранилище доверенных сертификатов хранит открытые ключи. Вам нужно будет сгенерировать сертификат Java для связи SSL. Вы можете использовать команду keygen в Windows, это, вероятно, будет самым простым решением.
Это шаги для создания Truststore на вашем локальном компьютере с помощью Keytool. Шаги по созданию доверенного хранилища для URL-адреса на вашем локальном компьютере.
1) Нажмите URL-адрес в браузере с помощью Chrome
2) Найдите значок i слева от URL-адреса в Chrome и щелкните его.
3) Установите флажок параметр сертификата и щелкните его, откроется диалоговое окно.
4) проверьте на вкладке «путь к сертификату» количество сертификатов, доступных для создания хранилища доверенных сертификатов.
7) После создания всех сертификатов откройте командную строку и перейдите по пути, по которому вы создали сертификаты.
8) предоставьте следующую команду Keytool, чтобы добавить сертификаты и создать хранилище доверенных сертификатов.
9) Введите команду keytool для всех сертификатов и добавьте их в хранилище доверенных сертификатов.
Хранилище ключей используется сервером для хранения закрытых ключей, а хранилище доверенных сертификатов используется сторонним клиентом для хранения открытых ключей, предоставленных сервером для доступа. Я сделал это в своем производственном приложении. Ниже приведены шаги для создания сертификатов Java для связи SSL:
Чтобы объяснить общий вариант использования / цель или непрофессионал:
TrustStore : как видно из названия, обычно он используется для хранения сертификатов. доверенных лиц. Процесс может поддерживать хранилище сертификатов всех доверенных сторон. которому он доверяет.
keyStore : используется для хранения ключей сервера (как открытых, так и частных). вместе с подписанным сертификатом.
Во время рукопожатия SSL
Клиент пытается получить доступ к https: //
Таким образом, Сервер отвечает предоставлением сертификата SSL (который хранится в его хранилище ключей).
Теперь клиент получает сертификат SSL и проверяет его через trustStore (т.е. в trustStore клиента уже есть предопределенный набор сертификатов, которым он доверяет). Это как: Могу ли я доверять этому серверу? Это тот же сервер, с которым я пытаюсь поговорить? Никаких атак посредников?
После того, как клиент проверяет, что он разговаривает с сервером, которому он доверяет, тогда связь SSL может происходить через общий секретный ключ.
Примечание: я не говорю здесь ничего об аутентификации клиента на стороне сервера. Если сервер также хочет выполнить аутентификацию клиента, он также поддерживает trustStore для проверки клиента. Тогда это становится взаимным TLS
Основы HTTPS, TLS, SSL. Создание собственных X.509 сертификатов. Пример настройки TLSv1.2 в Spring Boot
Привет, Хабр! В современном мире абсолютное большинство сайтов используют HTTPS (Google даже снижает рейтинг сайтов работающих по HTTP в поисковой выдаче), а подключение к различным системам происходит по протоколу TLS/SSL. Поэтому любой разработчик рано или поздно сталкивается с этими технологиями на практике. Данная статья призвана помочь разобраться, если вы совершенно не в курсе что это такое и как оно устроено. Мы разберем как работает соединение по протоколу TLS, как выпустить собственные сертификаты и настроем TLS в Spring Boot приложении. Поехали!
Что не так с HTTP?
Симметричное шифрование предполагает наличие общего ключа одновременно у отправителя и получателя, с помощью которого происходит шифровка и дешифровка данных. Данный тип не требователен к ресурсам, однако существенно страдает безопасность из-за опасности кражи ключа злоумышленником.
При использовании ассиметричного шифрования существует открытый ключ, который можно свободно распространять, и закрытый ключ, который держится в секрете у одной из сторон. Этот тип работает медленно, относительно симметричного шифрования, однако скомпрометировать закрытый ключ сложнее.
Что происходит на практике
Что такое Message Authentication Code или MAC? Это хэш, сгенерированный с использованием выбранной криптографической хэш-функции и разделяемого ключа, который добавляется сзади к сообщению. Перед отправкой данных отправитель вычисляет MAC для них, а получатель перед обработкой вычисляет MAC для принятого сообщения и сравнивает его с MAC этого принятого сообщения. Предназначен для проверки целостности, то есть что сообщение не было изменено при его передаче.
Для чего нужен идентификатор сессии? Как мы посмотрим далее, процесс установления TLS соединения затратен по времени и ресурсам. Предусмотрен механизм возобновления соединения с помощью отправки клиентом этого идентификатора. Если сервер тоже все еще хранит соответствующие настройки, то клиент и сервер смогут продолжить общение использую ранее выбранные алгоритмы и ключи.
Кем подписан сертификат корневого CA? А никем, нет инстанции выше корневого CA. Сертификат (открытый ключ) в этом случае подписан собственным закрытым ключом. Такие сертификаты называют самоподписанные (sefl-signed).
Сервер случайно генерирует число 6, передает клиенту числа p = 17, g = 3, Ys = 3 6 mod 17 = 15
Клиент случайно генерирует число 7 и возвращает серверу Yc = 3 7 mod 17 = 11
Сервер считает итоговое число 11 6 mod 17= 8, и клиент 15 7 mod 17 = 8
После этого соединение считается установленным, и происходит передача полезной информации
Двусторонний TLS
Двусторонний TLS или Two Way TLS или mutual TLS (mTLS) означает проверку сертификата клиента. Сервер после своего сообщения Certificate посылает запрос сертификата клиента CertificateRequest. Клиент в ответ отправляет Certificate, сервер производит проверку, аналогичную проверке сертификата сервера клиентом. Далее настройка TLS происходит в описанном выше порядке.
TLSv1.3
Стоит отметить, что все выше написанное относится к TLSv1.2, которая начинает понемногу устаревать. В 2018 году была разработана новая версия 1.3 в которой: были запрещены уже ненадежные алгоритмы, ускорен процесс соединения, переработан протокол рукопожатия и др. Интернет медленно но верно обновляется до TLSv1.3, однако все еще большинство сайтов работают по протоколу TLSv1.2. Поэтому информация в этой статье остается актуальной.
Выпускаем собственные сертификаты
Теперь, когда мы разобрали теорию, самое время приступить к практике! Нам понадобятся OpenSSL и keytool (входит в поставку JDK). Для начала создадим сертификат корневого CA, которым будем подписывать запросы на подпись сертификата клиента и сервера. Сгенерируем приватный ключ RSA зашифрованный AES 256 с паролем «password» длиной 4096 бит (меньше 1024 считается ненадежным) в файл CA-private-key.key:
Нет какого-то принятого стандарта расширений для файлов, связанных с сертификатами. Мы будем использовать:
Так как подписать сертификат другим сертификатом пока нельзя, подпишем запрос его же приватным ключом. Получившейся сертификат CA-self-signed-certificate.pem будет самоподписанным со сроком действия 1 день.
Теперь у нас есть сертификат, которому в будущем будут доверять наши клиент и сервер. Похожим образом сделаем приватные ключи и запросы на подпись сертификата для них:
После этого необходимо создать хранилище ключей с сертификатами (keystore) Server-keystore.p12 для использования в нашем приложении. Положим туда сертификат сервера, приватный ключ сервера и защитим хранилище паролем «password»:
Осталось только создать хранилище доверенных сертификатов (truststore): сервер будет доверять всем клиентам, в цепочке подписания которых есть сертификат из truststore. К сожалению, для Java сертификаты в truststore должны содержать специальный object identifier, а OpenSSL пока не поддерживает их добавление. Поэтому здесь мы прибегнем к поставляемому вместе с JDK keytool:
Для удобства, все описанные выше действия упакованы в bash script.
Настройка TLS в Spring Boot приложении
Основой для нашего проекта послужит шаблон с https://start.spring.io/ с одной лишь зависимостью Spring Web. Для включения TLS указываем в application.properties:
После этого указываем Spring тип keystore, путь к нему и пароль:
Для проверки доступа создадим минимальный контроллер:
Запускаем проект. Попробуем сделать запрос с помощью curl:
На этот раз все сработало, TLS в Spring Boot работает! Мы на этом не остановимся, добавим в приложение аутентификацию клиента (указываем truststore):
Запускаем и снова пытаемся выполнить запрос:
Очевидно, что сервер закрыл соединение, так как curl не предоставил никакого сертификата. Дополним запрос клиентским сертификатом и его закрытым ключом:
Итоги
В данной статье мы разобрались как работает протокол TLS и для чего он нужен. На практике научились создавать собственные сертификаты и использовать их в Java приложении на Spring Boot. Надеюсь, представленная информация оказалась Вам полезной. Спасибо за внимание!