Table of Contents
Java, сертификаты и подписанты
Слово "подписанты" было обнаружено в konqueror в процессе получения опыта, который позволил написать данную статью.
Итак, у вас есть Java-приложение (или даже много приложений) и вы хотите, например, организовать к нему доступ через SSL.
Как это ни странно, наибольшие проблемы создаёт не настройка веб-сервера, которая как правило сводится к редактированию одной-двух строчек в конфиге веб-сервера. Основные проблемы - в создании сертификата.
Самоподписанный сертификат
Самый простой случай, у вас всего одно приложение, других не намечается, ваши пользователи вполне готовы к тому, что при заходе будут видеть окошко, предупреждающее о том, что вас сертификат плох.
Вам достаточно проделать следующее:
keytool -genkey -alias NAME
После чего вы получите сертификат, подписанный самим собой. Всё что останется сделать - объяснить веб-серверу, в каком keystore брать сертификат, какой у него alias и какой пароль необходимо использовать.
Следует учитывать, что такие сертификаты в общем случае являются невалидными и особо секьюрные приложения просто откажутся с ними работать.
Собственный certificate authority
Второй случай, более сложный. Имеет смысл в ситуации, когда приложений больше одного и является более правильным в плане безопасности. Мы создадим собственный корневой сертификат, после чего каждый раз, когда нам понадобится сертификат для отдельного приложения, будем подписывать его корневым.
Сначала создадим certificate authority.
Для этого нам понадобится библиотека OpenSSL. Предупреждаю сразу, при возникновении ошибок она выдаёт совершенно неудовлетворительные сообщения. Как это терпят другие я не понимаю. OpenSSL имеет довольно много всяких опций, в которых легко запутаться, а случае ошибки см. выше. В связи с чем воспользуемся скриптом-обёрткой CA.sh
, идущей в комплекте с OpenSSL.
- Создаём certificate authority (внимание, certificate filename не указывать) Все поля кроме common name являютя необязательными.
/path/to/CA.sh -newca
В результате в файле demoCA/cacert.pem
мы получили публичный сертификат, а в файле demoCA/private/cakey.pem
приватный ключ. Приватный ключ не надо никуму показывать, он нужен для подписывания сертификатов данным.
- Создаём самоподписанный сертификат с помощью keytool аналогично предыдущему разделу.
keytool -genkey -alias NAME
- Создаём Certificate Signing Request (CSR, запрос на подписание сертификата). CSR будет создан в файле
newreq.pem
.
keytool -certreq -alias NAME -file newreq.pem
- Подписываем приватным ключом CRS.
/path/to/CA.sh -sign
- А вот здесь начинается магия. Есть два варианта дальнейших действий. Либо публичный сертификат устанавливается в хранилище доверенных сертификатов в JRE.
keytool -import -alias CA_NAME -file demoCA/cacert.pem -trustcacerts -keystore /${JAVA_HOME}/lib/security/cacerts
После чего в keystore добавляется нужный нам сертификат, который заместит самоподписанный.
keytool -import -file newcert.pem -alias NAME
Либо содержимое файла demoCA/cacert.pem
необходимо добавить в файл с подписанным сертификатом, после чего опять же добавить его в keystore.
keytool -import -file newcert.pem -alias NAME
Однако готов поспорить что оба из этих вариантов не сработают. Я более чем уверен, что вы получите сообщение об ошибке. Почему? Потому что класс sun.security.provider.X509Factory
, отвечающий за парсинг сертификатов, очень нежен и требует аккуратного с ним обращения. На ваше (и моё) счастье некто Крис Джонсон ещё в 2004'ом году описал1) возникающие проблемы и способы их решения. Так же в его статье вы найдёте ссылку на статью с Sun.com про keytool.
Сертификат, подписанный доверенным подписантом
Последний вариант во многом похож на предыдущий за исключением того, что ваш корневой сертификат будет подписан кем-то из доверенных компаний (Verisign, Thawte и др.). Плюсом этого будет то, что при заходе на ваш сайт пользователям вашего сайта не будет показываться никаких предупреждений, а будет сообщаться, что сертификат является подлинным. Три НО - это стоит денег, сертификаты подписывают только на время (как проавило год или два) и процесс требует некоторых бюрократических действий. Каких - не знаю, т.к. сам ещё этот процесс не проходил.
Вот и всё. Удачного вам SSL'я.