Анонс
В предыдущей статье «Сам себе PKI: Теория на примере Let’s Encrypt» мы рассмотрели теорию и разобрали пример, как происходит установка HTTPS соединения между браузером и веб-сайтом при использовании сертификатов Let’s Encrypt. В этой статье перейдем к практике и самостоятельно реализуем ту же самую схему:
-
Сначала вручную (с помощью OpenSSL) пройдем цепочку генерации и использования самоподписанных сертификатов в HTTPS сервере.
-
Далее развернем собственный удостоверяющий центр Smallstep и будем получать сертификаты, подписанные им.
Схема PKI остаётся той же, только изменяются компоненты:
-
В качестве CA вместо Let’s Encrypt, будет использоваться OpenSSL и CA Smallstep.
-
В роли Web-сервера вместо Интернет веб-сайта, будет выступать простой HTTPS сервер, запущенный на Node.js.
![How to generate a self-signed SSL certificate using OpenSSL? [closed]](https://habrastorage.org/getpro/habr/upload_files/7fb/3e6/a10/7fb3e6a10d4a8a10f79f499d31f12b89.png)
Практика Self-signed certificate
OpenSSL
Начнем с классики криптографии OpenSSL. Сейчас широко используется версия 1.1.1, но ее поддержка заканчивается в 2023. Следующая версия 3.0 будет поддерживаться до 2026 года. Проверка установленной версии:
OpenSSL 1.1.1k FIPS 25 Mar 2021
Если OpenSSL не установлен, то его можно установить на всех востребованных платформах.
Реализация TLS
-
Для нашего CA генерируем приватный ключ 2048-бит RSA. Администратор CA должен хранить его в секрете от всех:
openssl genrsa -out root_ca.key 2048
-
Далее для нашего CA генерируем X.509 сертификат на 365 дней (root_ca.crt) и подписываем его приватным ключом (root_ca.key). Получается самоподписанный сертификат, его можно и нужно будет скопировать на все компьютеры, между которыми необходимо организовать TLS соединение. При ответах на вопросы, которые будет задавать OpenSSL, можно указывать произвольные данные, CA я назвал «My CN»:
openssl req -x509 -new -key root_ca.key -days 365 -out root_ca.crt
-
Смотрим получившийся сертификат, убеждаемся, что данные в нем корректные:
openssl x509 -text -in root_ca.crt
-
Генерируем приватный ключ для HTTPS сервера, его нужно будет скопировать только на компьютер, на котором он будет работать и никуда больше:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=xx.xx.xx.xx/CN=server/CN=server.example.com" -out server.csr
-
Можно посмотреть получившийся запрос на сертификат и убедиться в его корректности:
openssl req -text -in server.csr
-
Теперь генерируем сертификат X.509 (server.crt) на 365 дней для HTTPS сервера и подписываем его приватным ключом CA (root_ca.key):
openssl x509 -req -in server.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out server.crt -days 365 -extensions SAN -extfile openssl.cnf
-
Файл openssl.cnf должен содержать список SAN (Subject Alternative Name) идентичный тому, что был в CSR запросе на сертификат:
[SAN]
subjectAltName = @alt_names
[alt_names]
IP.1 = xx.xx.xx.xx
DNS.1 = server
DNS.2 = server.example.com
-
Можно посмотреть на получившийся сертификат и убедиться в его корректности:
openssl x509 -text -in root_ca.crt
-
С ключами и сертификатами закончили, переходим к запуску HTTPS сервера. Копируем следующие файлы на компьютер, на котором будет работать HTTPS сервер:
-
Пишем простейший HTTPS сервер, на JS:
const fs = require('fs');
const https = require('https');
https
.createServer(
{
requestCert: false,
rejectUnauthorized: false,
ca: fs.readFileSync('root_ca.crt'),
cert: fs.readFileSync('server.crt'),
key: fs.readFileSync('server.key')
},
(req, res) => {
console.log("req.client.authorized: ", req.client.authorized)
if (req.client.authorized) {
const cert = req.socket.getPeerCertificate(false) // true - получить все сертификаты, false - последний
console.log("cert: ", cert)
}
res.end('Hello, world!');
}
)
.listen(9443);
-
Запускать данный скрипт будем с помощью Node.js. Если Node.js не установлен, то устанавливаем:
sudo yum groupinstall 'Development Tools'
sudo yum install nodejs
-
Проверяем, что Node и Npm установились успешно:
-
Проверяем сервер curl-ом:
При первом запросе возникнет ошибка:
curl: (60) SSL certificate problem: self signed certificate in certificate chain
Это значит, что самоподписанный корневой сертификат нашего CA (root_ca.crt) не находится в хранилище доверительных сертификатов. Процесс загрузки сертификатов в это хранилище специфичен для операционной системы. Приведу алгоритм для RH Linux:
-
Если сертификат не в PEM (текстовом) формате, то его надо сконвертировать в текстовой формат:
openssl x509 -in root_ca.crt -out root_ca.pem -outform PEM
-
Копируем сертификат в определенный каталог на сервере. ДляRH 7 и выше это каталог:
-
Выполняем команду обновления хранилища сертификатов:
-
Теперь curl проходит
-
на Windows есть специфика — в curl необходимо добавлять параметр «ssl-no-revoke», чтобы не проверялся список отозванных сертификатов:
-
При этом сервер выведет в консоль строку:
Это значит, что мы установили TLS соединение только с проверкой сертификата сервера, а не клиента. Переходим к mTLS.
Реализация mTLS
В коде сервера включаем mTLS, а именно выставляем в true параметр requestCert, чтобы HTTPS сервер запрашивал клиентский сертификат и параметр rejectUnauthorized, чтобы сервер отклонял запросы клиентов, которые не прошли авторизацию:
{
requestCert: true,
rejectUnauthorized: true,
}
Алгоритм генерации клиентских сертификатов аналогичен серверным.
-
Генерируем приватный ключ для клиента:
openssl genrsa -out client.key 2048
-
Генерируем запрос на сертификат CSR со списком CN:
openssl req -new -key client.key -subj "/CN=xx.xx.xx.xx/CN=client/CN=client.example.com" -out client.csr
-
Генерируем сертификат для клиента и подписываем его приватным ключом CA:
openssl x509 -req -in client.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out client.crt -days 365 -extensions SAN -extfile openssl.cnf
Файл openssl.cnf — такой же как и для сервера, только вместо «server» пишем «client».
-
Копируем следующие файлы на компьютер, на котором будет работать клиент:
-
Теперь если просто вызвать curl:
-
То произойдет ошибка авторизации
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
-
Поэтому вызываем curl с дополнительными параметрами, в которых указываем ключ клиента и сертификаты клиента и СА:
curl --cert ./client.crt --key client.key --cacert root_ca.crt https://server.example.com:9443
-
Теперь запрос проходит, при этом сервер выведет в консоль следующую строку и далее содержимое полученного от клиента сертификата:
Это значит, что мы установили mTLS соединение с проверкой сертификата как сервера, так и клиента. Теперь установим mTLS из браузера.
Реализация mTLS в браузере
Если просто запустить наш запрос к серверу (https://server.example.com:9443) из браузера, то выдается ошибка клиентского сертификата ERR_BAD_SSL_CLIENT_AUTH_CERT. Рабочие адреса закрасил желтым:
Для загрузки в браузер клиентский сертификат и приватный ключ надо сконвертировать в формат p12. Этот формат определяется стандартом PKCS #12 и является архивом для хранения нескольких объектов. В нашем случае файл будет хранить клиентский сертификат и его приватный ключ. Понятно, что приватный ключ — это чувствительная к разглашению информация и ее владелец не должен выкладывать p12 сертификат в открытый доступ. Для конвертации тоже используем OpenSSL:
openssl pkcs12 -inkey client.key -in client.crt -export -out client.p12
Импортируем client.p12 в браузер. Для этого, например в Chrome, идем в меню: Settings / Privacy and security / Manage certificates, в открывшемся окне нажимаем Import, выбираем наш файл client.p12 и место хранения «Personal». Видим, что клиентский сертификат, выданный нашим удостоверяющим центром «My CN», появился в хранилище персональных сертификатов:
Вызываем запрос заново, уже лучше, но браузер все равно пишет, что соединение не безопасно. Это из-за того, что клиентский сертификат выдан удостоверяющим центром «My CN», которого нет в списке доверительных CA (Trusted Root Certification Authorities).
Добавляем корневой сертификат нашего CA (root_ca.crt) в Trusted Root Certification Authorities. Делается с помощью того же вызова Import, что и для клиентского сертификата, но хранилище указываем Trusted Root Certification Authorities. Проверяем, что наш CA «My CN» появился в хранилище:
Повторяем наш запрос (https://server.example.com:9443). При первом запросе браузер находит подходящий клиентский сертификат и просит явно подтвердить его использование:
Дальнейшие вызовы проходят без запросов на подтверждение клиентского сертификата:
Если щелкнуть на замочке а адресной строке, то можно посмотреть сертификат сервера и убедиться, что мы взаимодействуем с правильным сервером (Issued to: server.example.com), сертификат которому выдан нашим удостоверяющим центром (Issued by: My CN) и время действия сертификата еще не прошло (Valid to: 31.05.2023):
Таким образом мы организовали mTLS соединение из браузера. Далее приведу для справки несколько дополнительных возможностей OpenSSL, которые могут пригодиться в процессе работы.
Дополнительные возможности OpenSSL
Конвертация форматов сертификатов
-
Конвертируем сертификат в der (бинарный формат):
openssl x509 -outform der -in client.crt -out client.der
-
Конвертируем сертификат в PEM (текстовой формат)
openssl x509 -inform der -in client.cer -out client.pem
Отладка с помощью OpenSSL
-
Проверка, что сертификат подписан определенным (root_ca.pem) удостоверяющим центром:
openssl verify -verbose -x509_strict -CAfile root_ca.pem server.crt
openssl s_server -accept 9443 -cert server.crt -key server.key
-
Запускаем OpenSSL client
openssl s_client -connect xx.xx.xx.xx:9443 -prexit -showcerts -state -status -tlsextdebug -verify 10
-
При вызове curl параметр:
-
-k — позволяет подсоединяться к серверу без проверки цепочки сертификатов (certificate path validation).
-
—ssl-no-revoke — предотвращает проверку отозванных сертификатов
-
Практика CA Smallstep
Установка Smallstep и CLI step
CA Smallstep — это open source CA, который можно развернуть локально для автоматического получения X.509 сертификатов. На официальном сайте есть ряд инструкций по его установке и настройке. Для экспериментов я использовал вариант с docker:
-
Краткая выжимка из инструкции по установке на RH Linux. Сначала устанавливаем docker:
sudo yum -y update
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum -y install docker-ce
sudo systemctl start docker
-
Проверяем корректность установки docker:
sudo docker run hello-world
sudo docker pull smallstep/step-ca
-
Инициализируем наш CA:
docker run -it -v step:/home/step smallstep/step-ca step ca init
должна вернуться строка:
На этом же или другом компьютере по инструкции устанавливаем утилиту CLI step. Краткая выжимка:
-
Загружаем бинарник step: https://github.com/smallstep/cli/releases/tag/v0.19.0
tar -xf step_linux_0.19.0_386.tar.gz
-
Копируем утилиту step в /usr/bin
-
Регистрируем CLI step для использования с нашим CA. Этот процесс называется «bootstrap». Значение параметра «ca-url» — это IP и порт, на котором запущен Smallstep CA, «fingerprint » — это сохраненное значение при инициализации CA:
-
Проверка связи с CA:
step ca health
должна вернуться строка:
Все готово для генерации ключей и сертификатов.
Генерация ключей и сертификатов
Также как и в случае с OpenSSL, сначала генерируем ключ и сертификат для сервера и установки TLS соединения, потом для клиента и установки mTLS.
-
В отличии от OpenSSL, CA Smallstep может одновременно сформировать приватный ключ сервера 2048-бит RSA (server.key) и запрос на сертификат (server.csr). В запросе явно указываем, что пароль должен быть пустой (no-password), xx.xx.xx.xx — это IP адрес сервера, для которого генерируется запрос:
step certificate create --csr --no-password --insecure --kty=RSA --size=2048 "xx.xx.xx.xx" server.csr server.key
-
Подписываем сертификат на нашем CA Smallstep:
step ca sign server.csr server.crt
-
Смотрим полученный сертификат:
step certificate inspect server.crt
-
Получаем с CA Smallstep его корневой сертификат:
step ca root root_ca.crt
-
Смотрим корневой сертификат:
step certificate inspect root_ca.crt
-
Аналогично OpenSSL копируем ключи и сертификаты на наш HTTPS сервер:
-
Проверяем сервер curl-ом:
Все нормально, теперь генерируем ключ и сертификат для клиента.
-
Аналогично серверу одновременно формируем приватный ключ клиента 2048-бит RSA (client.key) и запрос на сертификат (client.csr). Явно указываем, что пароль должен быть пустой (no-password), xx.xx.xx.xx — это IP адрес клиента, для которого генерируется запрос:
step certificate create --csr --no-password --insecure --kty=RSA --size=2048 "xx.xx.xx.xx" client.csr client.key
-
Подписываем сертификат на CA:
step ca sign client.csr client.crt
step certificate inspect client.crt
-
Получаем корневой сертификат CA:
step ca root root_ca.crt
-
Смотрим корневой сертификат:
step certificate inspect root_ca.crt
-
Копируем на клиента:
-
Для проверки вызываем curl с параметрами:
curl --cert ./client.crt --key client.key --cacert root_ca.crt https://xx.xx.xx.xx:9443
Отлично — mTLS тоже работает с выданными CA Smallstep сертификатами!
Дополнительные возможности CA Smallstep
С помощью CLI step можно проверить необходимость обновления сертификата:
step certificate needs-renewal server.crt
-
Если обновление не требуется возвращается строка:
certificate does not need renewal
-
Если требуется, то строка пустая и тогда необходимо обновить сертификат:
step ca renew server.crt server.key
-
При необходимости сертификат можно отозвать, в этом случае его невозможно будет продлить, только получить заново:
step ca revoke --cert server.crt --key server.key
-
Посмотреть все сертификаты в цепочке:
step certificate inspect server.crt --bundle
-
Запуск CLI step в режиме отладки:
STEPDEBUG=1 step /команда/
Заключение
В данной статье мы рассмотрели две возможности генерации ключей и сертификатов для клиента и сервера:
-
С помощью OpenSSL.
-
Используя CA Smallstep.
И двумя способами установили TLS и mTLS соединения:
-
С помощью curl.
-
Из браузера, загрузив в него клиентский и корневой сертификаты.
Теперь у нас есть понимание, как организовать свою систему PKI с помощью CA любого производителя, т.к. логика взаимодействия у всех аналогичная. Более того, большинство CA используют под капотом OpenSSL, оборачивая его в свой API.
В этой статье я объясню, как создать сертификат SSL на сервере Ubuntu 18.04 с веб-сервером Nginx.
SSL означает «Secure Sockets Layer», который является стандартной технологией безопасности, предназначенной для создания зашифрованной связи между веб-сервером и веб-сервером.
Эта ссылка гарантирует, что вся информация, передаваемая между сервером и браузером, остается конфиденциальной и безопасной.
Основная цель сертификатов SSL заключается в обеспечении безопасности веб-сайта и шифровании данных, передаваемых между клиентом и браузером, для предотвращения кражи конфиденциальной информации, такой как данные кредитной карты, номера счетов и пароли и т. д.
Самоподписанный сертификат – это сертификат, подписанный лицом, создающим его, а не доверенным центром сертификации (ЦС).
Большинство клиентов и организаций испытывают соблазн использовать самоподписанные SSL-сертификаты вместо выпущенных и проверенных доверенным центром сертификации в основном из-за разницы в стоимости.
Но он по-прежнему обеспечивает такой же уровень шифрования
Предпосылки
Хорошо настроенный сервер с привилегиями root и библиотекой OpenSSL.
Библиотека OpenSSL требуется для создания собственного сертификата.
Выполните следующую команду на своем сервере ubuntu, чтобы узнать, установлен ли у вас OpenSSL.
# which openssl /usr/bin/openssl
Если which команда не вернула двоичный файл, нам нужно будет установить его с помощью команды:
# apt install openssl
Создание самоподписанного сертификата
SSL состоит в основном из двух частей: один – это закрытый ключ и другой публичный сертификат.
Ключ SSL хранится на сервере ограниченным пользователем root.
Он фактически используется для шифрования содержимого, отправленного клиентам.
Открытый SSL-сертификат предоставляется всем, кто запрашивает контент.
Его можно использовать для дешифрования содержимого, подписанного связанным с ним частным ключом SSL.
Здесь я использую эту команду для создания сертификата, а именно example.com.crt и private key example.com.key, используя инструмент OpenSSL.
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/example.com.key -out /etc/ssl/certs/example.com.pem
Пожалуйста, ознакомьтесь с информацией по каждому из вариантов ниже:
req: Эта подкоманда используется для создания нового сертификата X.509. «X.509» – это стандарт инфраструктуры открытых ключей, который поддерживает SSL и TLS для управления ключами и сертификатами.
-x509: Это дополнительно изменяет предыдущую подкоманду, сообщая утилите, что мы хотим сделать сертификат.
-nodes: Это используется, чтобы пропустить опцию passphrase для защиты нашего сертификата.
-days 365: эта опция устанавливает срок действия сертификата в днях. Мы устанавливаем его на год.
-newkey rsa: 2048: Указывает, что мы хотим сгенерировать новый ключ RSA длиной 2048 бит вместе с сертификатом.
-keyout: Этот параметр сообщает OpenSSL, куда поместить сгенерированный файл закрытого ключа.
-out: Этот параметр указывает OpenSSL, где размещать сгенерированный сертификат.
Во время выполнения этой команды нам будет предложено предоставить данные о домене / клиенте для создания запроса подписи сертификата (CSR).
Вы можете предоставить эти данные по мере необходимости.
Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]:Victoria Locality Name (eg, city) []:Melbourne Organization Name (eg, company) [Internet Widgits Pty Ltd]:Linoxide LLC Organizational Unit Name (eg, section) []:Web Common Name (e.g. server FQDN or YOUR name) []:example.com Email Address []:admin@example.com
Теперь у нас есть новый самоподписанный сертификат, а секретный ключ – это: /etc/ssl/certs/example.com.pem и /etc/ssl/private/example.com.key.
Затем мы должны создать сильную группу Диффи-Хеллмана.
Вы можете запустить эту команду для ее создания.
#o penssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Это может занять некоторое время, но когда это будет сделано, у нас будет сильная группа DH в /etc/ssl/certs/dhparam.pem, которую мы можем использовать в нашей конфигурации.
Настройка Nginx для использования самоподписанных сертификатов
Прежде чем мы начнем, мы должны убедиться, что веб-сервер Nginx установлен на нашем сервере Ubuntu 18.04.
Если он не установлен, вы можете установить его с помощью этой простой команды:
#apt install nginx
Я установил и включил эту службу на своем сервере.
# nginx -v nginx version: nginx/1.14.0 (Ubuntu) #systemctl enable nginx #systemctl start nginx #systemctl status nginx
Шаг 1. Создание конфигурации фрагмента с данными SSL-сертификата.
Давайте создадим новый файл конфигурации snippet, а именно «self-signed.conf», для указания наших сгенерированных сведений о самоподписываемом сертификате внутри папки фрагмента Nginx: /etc/nginx/snippets/, как показано ниже:
# cat /etc/nginx/snippets/self-signed.conf # Self signed certificates generated by the ssl-cert package # Don't use them in a production server! ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key;
Здесь нам нужно указать наш путь к сертификату: /etc/ssl/certs/example.com.pem и путь ключа: /etc/ssl/private/example.com.key для директивы, как указано выше.
Шаг 2. Создание конфигурации фрагмента для поддержки параметров Strong и Secure SSL, преодолевающих возможные уязвимости SSL.
Во-вторых, нам необходимо поддерживать полностью функциональную и надежную конфигурацию SSL-сервера, защищающую наш сервер от всех возможных уязвимостей SSL.
Я настроил свой Nginx с помощью сильного набора SSL-шифров и включил некоторые дополнительные функции для обеспечения безопасности сервера.
Все эти параметры включены в файл: /etc/nginx/snippets/ssl-params.conf
cat /etc/nginx/snippets/ssl-params.conf ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling off; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;
Как вы можете видеть, мы установили параметр ssl_dhparam для указания на файл Diffie-Hellman, который мы сгенерировали ранее.
После внесения этих изменений вы можете сохранить конфигурацию и выйти.
Шаг 3. Обновление виртуального хоста домена с помощью приведенных выше настроек фрагмента для включения SSL.
Мы готовы с нашей необходимой конфигурацией фрагментов, теперь мы можем включить их в наш виртуальный хост домена и включить SSL.
Здесь, в этой статье, я использую файл конфигурации по умолчанию Nginx, расположенный по адресу /etc/nginx /sites-available/default.
Я изменил этот файл, чтобы включить SSL и получить сгенерированные самоподписанные сертификаты.
См. Измененный раздел ниже в этой конфигурации:
cat /etc/nginx/sites-available/default # server { listen 80 default_server; listen [::]:80 default_server; # SSL configuration listen 443 ssl default_server; listen [::]:443 ssl default_server; # # Note: You should disable gzip for SSL traffic. # See: https://bugs.debian.org/773332 # # Read up on ssl_ciphers to ensure a secure configuration. # See: https://bugs.debian.org/765782 # # Self signed certs generated by the ssl-cert package # Don't use them in a production server! # include snippets/self-signed.conf; include snippets/ssl-params.conf;
Теперь мы можем сохранить эти конфигурации и перезапустить службу Nginx, чтобы эти изменения вступили в силу.
# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful #systemctl restart nginx
Тестирование
Это наш последний шаг, когда мы можем открыть наш браузер и попытаться получить доступ к нашему серверному IP по URL >> https: // Server_IP или Hostname.
Он отобразит предупреждение о безопасности, так как мы используем самоподписанный сертификат, вы можете игнорировать это предупреждение и нажать ок,чтобы продолжить дальше, как показано в снимке.
I had to puzzle my way through self-signed certificates on Windows by combining bits and pieces from the given answers and further resources. Here is my own (and hopefully complete) walk-through. Hope it will spare you some of my own painful learning curve. It also contains infos on related topics that will pop up sooner or later when you create your own certs.
Create a self-signed certificate on Windows 10 and below
Don’t use makecert.exe. It has been deprecated by Microsoft.
The modern way uses a Powershell command.
New-SelfSignedCertificate -DnsName "*.dev.local", "dev.local", "localhost" -CertStoreLocation cert:\LocalMachine\My -FriendlyName "Dev Cert *.dev.local, dev.local, localhost" -NotAfter (Get-Date).AddYears(15)
Windows 8, Windows Server 2012 R2:
New-SelfSignedCertificate -DnsName "*.dev.local", "dev.local", "localhost" -CertStoreLocation cert:\LocalMachine\My
Older Windows versions:
The resulting certificate
Both of the above commands create a certificate for the domains localhost
and *.dev.local
.
The Win10 version additionally has a live time of 15 years and a readable display name of «Dev Cert *.dev.local, dev.local, localhost».
After creation the cert will be immediately available in any HTTPS bindings of IIS (instructions below).
Trust the certificate (on the machine where you created it)
The new cert is not part of any chain of trust and is thus not considered trustworthy by any browsers. To change that, we will copy the cert to the certificate store for Trusted Root CAs on your machine:
In the left column choose «Certificates (Local Computer) / Personal / Certificates».
Find the newly created cert (in Win 10 the column «Friendly name» may help).
Select this cert and hit Ctrl-C to copy it to clipboard.
In the left column choose «Certificates (Local Computer) / Trusted Root CAs / Certificates».
Hit Ctrl-V to paste your certificate to this store.
The certificate should appear in the list of Trusted Root Authorities and is now considered trustworthy.
Trust the certificate (on a different machine)
To trust the same cert on a different machine you have to export it on the machine where you created it and import it on the other machine.
Then copy the resulting file to the target machine, right-click and install the cert into the store «Local Computer / Trusted Root CAs». After that all applications that use the windows cert store (i.e. Chrome and IE but NOT Firefox) should trust your self-signed certificate.
Use in IIS
(We are back on the machine, where you created the new certificate!)
Add to hosts
Also add your host name to C:\Windows\System32\drivers\etc\hosts:
127.0.0.1 myname.dev.local
Now Chrome and IE should treat the certificate as trustworthy and load your website when you open up https://myname.dev.local
.
Firefox maintains its own certificate store. To add your cert here, you must open your website in FF and add it to the exceptions when FF warns you about the certificate.
For Edge browser there may be more action needed (see further down).
Test the certificate
To test your certs, Firefox is your best choice. (Believe me, I’m a Chrome fan-boy myself, but FF is better in this case.)
Here are the reasons:
- Firefox uses its own SSL cache, which is purged on shift-reload. So any changes to the certs of your local websites will reflect immediately in the warnings of FF, while other browsers may need a restart or a manual purging of the windows SSL cache.
- Also FF gives you some valuable hints to check the validity of your certificate: Click on Advanced when FF shows its certificate warning. FF will show you a short text block with one or more possible warnings in the central lines of the text block:
The certificate is not trusted because it is self-signed.
This warning is correct! As noted above, Firefox does not use the Windows certificate store and will only trust this certificate, if you add an exception for it right within Firefox. The button to do this is right below the warnings.
This warning shows, that you did something wrong. The (wildcard) domain of your certificate does not match the domain of your website. The problem must be solved by either changing your website’s (sub-)domain or by issuing a new certificate that matches. In fact you could add an exception in FF even if the cert does not match, but you would never get a green padlock symbol in Chrome with such a combination.
Firefox can display many other nice and understandable cert warnings at this place, like expired certs, certs with outdated signing algorithms, etc. I found no other browser that gave me that level of feedback to nail down any problems.
Which (sub-)domain pattern should I choose to develop?
In the above New-SelfSignedCertificate command we used the wildcard domain *.dev.local
.
You may think: Why not use *.local
?
Simple reason: It is illegal as a wildcard domain.
Wildcard certificates must contain at least a literal second level domain name. The asterisk (*) is allowed only from the third level upwards.
So, domains of the form xyz.local
are ok when you develop under HTTP and you don’t need certs. But if you use that domain pattern with HTTPS you would be forced to issue a new matching certificate for each new project that you start. Better use domains of the form xyz.dev.local
and a single wildcard cert for *.dev.local
.
Important side notes:
- Valid host domains may ONLY contain letters a through z, digits, hyphens and dots. No underscores allowed! Some browsers are really picky about this detail and can give you a hard time when they stubbornly refuse to match your domain
motör_head.dev.local
to your wildcard pattern*.dev.local
. They will comply when you switch tomotoer-head.dev.local
. - A wildcard in a certificate will only match ONE label (= section between two dots) in a domain, never more.
*.dev.local
matchesmyname.dev.local
but NOTother.myname.dev.local
! - Multi level wildcards (
*.*.dev.local
) are NOT possible in certificates.
Soother.myname.dev.local
can only be covered by a wildcard of the form*.myname.dev.local
. As a result, it is best not to use a forth level domain part. Put all your variations into the third level part. This way you will get along with a single certificate for all your dev sites.
The problem with Edge
(This is about the old MS Edge version – non-Chromium. I don’t think this still applies to the new Chromium version. But I’m not sure.)
CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe
More infos about Edge and Network Isolation can be found here:
https://blogs.msdn.microsoft.com/msgulfcommunity/2015/07/01/how-to-debug-localhost-on-microsoft-edge/
В наше время использование HTTPS становится обязательным для всех сайтов и веб-приложений. Но в процессе разработки возникает проблема корректного тестирования. Естественно, Let’s Encrypt и другие CA не выдают сертификаты для localhost.
Традиционно есть два решения.
- Самоподписанные сертификаты, сгенерированные через openssl или др. Вот самый простой способ сгенерировать приватный ключ и самоподписанный сертификат для localhost:
openssl req -x509 -out localhost.crt -keyout localhost.key \ -newkey rsa:2048 -nodes -sha256 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Но такой сертификат вызовет ошибки доверия в браузерах, потому что в доверенном хранилище отсутствует соответствующий центр сертификации.
- Трюк с регистрацией нового домена типа localhost.example.com, который локально ресолвится в 127.0.0.1 (в /etc/hosts), с получением обычного сертификата для данного домена. Но такая махинация сомнительна с точки зрения безопасности — по крайней мере, для публичных сервисов подобный ресолвинг делать крайне не рекомендуется из-за возможной MiTM-атаки со сменой на враждебный IP-адрес. Если ограничиться только локальной машиной, то может это и подходящий вариант, хотя тоже возникают некоторые сомнения. К тому же, такой сертификат могут отозвать. В любом случае, есть вариант проще и безопаснее (см. ниже).
Речь идёт о mkcert — простой утилите для генерации локально-доверенных сертификатов с собственным центром сертификации. Она работает под всеми ОС и не требует какой-то конфигурации.
Версия для Linux
Сначала нужно установить certutil
.
sudo apt install libnss3-tools
-или-
sudo yum install nss-tools
-или-
sudo pacman -S nss
brew install mkcert
или собрать из исходников:
go get -u github.com/FiloSottile/mkcert
$(go env GOPATH)/bin/mkcert
Версия для macOS
brew install mkcert
brew install nss # if you use Firefox
Версия для Windows
choco install mkcert
-или-
scoop install mkcert
Наличие локального центра сертификации — самое важное принципиальное отличие mkcert от openssl и самоподписанных сертификатов, потому что при запуске такого CA локально не возникает никаких ошибок доверия.
В принципе, запустить и настроить собственный CA можно и другими средствами, но это требует нетривиальных знаний и навыков. Здесь всё делает само собой, без всяких дополнительных ключей и настроек. Просто устанавливаем программу — и она автоматически создаёт локальный центр сертификации и прописывает его в доверенное хранилище системы и доверенное хранилище Firefox.
$ mkcert -install
Created a new local CA at "/Users/filippo/Library/Application Support/mkcert"
The local CA is now installed in the system trust store! ️
The local CA is now installed in the Firefox trust store (requires restart)!
Возникла необходимость (для внутренних целей) сгенерировать самоподписанный сертификат. Для этого был использован OpenSSL (Linux).
Итак, создаём самоподписанный SSL сертификат с помощью OpenSSL. Для начала нам необходимо установить пакет OpenSSL. Устанавливаем его так:
# apt-get install openssl
После установки OpenSSL, создадим директории, в которых будут лежать сертификаты и ключи:
# mkdir /home/ssl/
Создаем самоподписанный SSL сертификат так:
# openssl req -x509 -newkey rsa:2048 -days 365 -keyout /home/ssl/my_key.key -out /home/ssl/my_cert.crt
Нас попросят ввести пароль к ключу. Вводим пароль, не менее 4 символов (и еще раз). Затем нас попросят ввести данные о сертификате. Если какие-то данные Вам не нужны можете просто пропустить и нажать Enter, будет использовано значение по-умолчанию (в квадратных скобках).
Давайте рассмотрим по порядку, что нам предлагают ввести:
В итоге мы получили два файла, ключ и сертификат. Ключ – это секретный ключ, публичный ключ находиться в теле самого сертификата.
Ключ без пароля
Если Вы, например, используете сертификат и ключ в веб-сервере, то пароль на ключе будет мешать нормальной работе. Поэтому лучше сгенерировать ключ без пароля. Добавляем параметр -nodes, в результате секретный ключ не будет зашифрован паролем.
# openssl req -x509 -nodes -newkey rsa:2048 -days 365 -keyout /home/ssl/my_key.key -out /home/ssl/my_cert.crt
Так же можно ещё добавить параметр -subj — этот тот кому принадлежит сертификат, то что мы вводили в интерактивном режиме (название организации, мыло и так далее). Можно эти параметры сразу указать в команде.
# openssl req -x509 -nodes -newkey rsa:2048 -days 365 -keyout /home/ssl/my_key.key -out /home/ssl/my_cert.crt -subj /C=/ST=/L=/O=/CN=unlix.ru
В примере выше пропускаем все поля, кроме CN (Common Name).
Чтобы просмотреть сертификат выполняем:
# openssl x509 -noout -text -in /home/ssl/my_cert.crt
Подключение по HTTPS – признак надежности и безопасной передачи данных. Чтобы реализовать безопасное подключение по HTTPS, нужно иметь SSL сертификат. В статье расскажем, как сгенерировать самоподписанный сертификат (self signed), а также как импортировать файл сертификата в формате .pfx. После, покажем установку и применение сертификатов к сайту в веб – сервере Microsoft IIS (Internet Information Services).
В статье мы используем IIS (Internet Information Services) версии 10.0.14393.0
Создание и установка самоподписанного сертификата
Открываем IIS Manager. Далее, в меню слева (раздел Connections) нажимаем на корень (как правило это хостнейм вашей машины) и в открывшейся в центральной части рабочей области дважды кликаем левой кнопкой на Server Certificates:
IIS так же можно запустить из под Administrative Tools
Указываем имя для нашего сертификата и нажимаем «OK». Далее, выбираем наш сайт в меню слева:
Как только нажали на наш сайт, выбираем в правом поле меню Bindings, далее, редактируем текущее HTTPS подключение (по 443 порту) нажав Edit и выбираем сгенерированный самоподписанный SSL сертификат.
Нажимаем ОК. После, открываем командную строку cmd и перезагружаем IIS сервер командой:
iisreset /restart
Кстати, для рестарта, можно использовать просто команду
iisreset
без ключаrestart
Импорт сертификата .pfx
Аналогично как и с самоподписанным сертификатом (раздел Connections) нажимаем на корень и кликаем на Server Certificates. Далее, справа, нажимаем Import:
Открываем на .pfx файл:
Когда для вас создавали .pfx, на него установили пароль – введите этот пароль в поле ниже и нажмите OK.
По окончанию, снова рестартуем IIS:
iisreset /restart
Рекомендуем
In a LAN (Local Area Network) we have a server computer, here named xhost running Windows 10, IIS is activated as WebServer. We must access this computer via Browser like Google Chrome not only from localhost through https://localhost/ from server itsself, but also from other hosts in the LAN with URL https://xhost/ :
https://localhost/
https://xhost/
https://xhost.local/
...
With this manner of accessing, we have not a fully-qualified domain name, but only local computer name xhost here.
Or from WAN:
https://dev.example.org/
...
You shall replace xhost by your real local computer name.
None of above solutions may satisfy us. After days of try, we have adopted the solution openssl.exe. We use 2 certificates — a CA (self certified Authority certificate) RootCA.crt and xhost.crt certified by the former. We use PowerShell.
Create and change to a safe directory
cd C:\users\so\crt
Generate RootCA. pem, RootCA. key & RootCA. crt as self-certified Certification Authority
openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt
Make request for certification
C: Country
ST: State
L: locality (city)
O: Organization Name
Organization Unit
CN: Common Name
openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"
Get xhost. crt certified by RootCA. pem
openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt
with extfile domains.ext file defining many secured ways of accessing the server website:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = xhost
DNS.3 = xhost.local
DNS.4 = dev.example.org
DNS.5 = 192.168.1.2
Make xhost. pfx PKCS #12,
openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt
Import xhost. pfx in iis10
installed in xhost computer (here localhost). and Restart IIS service.
IIS10 Gestionnaire des services Internet (IIS) (%windir%\system32\inetsrv\InetMgr.exe)
Bind ssl with xhost. local certificate on port 443.
Restart IIS Service.
Import RootCA. crt into Trusted Root Certification Authorities
via Google Chrome in any computer that will access the website https://xhost/.
The browser will show this valid certificate tree:
RootCA-CA
|_____ xhost.local
No Certificate Error will appear through LAN, even through WAN by https://dev.example.org.
Here is the whole Powershell Script socrt.ps1 file to generate all required certificate files from the naught:
#
# Generate:
# RootCA.pem, RootCA.key RootCA.crt
#
# xhost.key xhost.csr xhost.crt
# xhost.pfx
#
# created 15-EEC-2020
# modified 15-DEC-2020
#
#
# change to a safe directory:
#
cd C:\users\so\crt
#
# Generate RootCA.pem, RootCA.key & RootCA.crt as Certification Authority:
#
openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt
#
# get RootCA.pfx: permitting to import into iis10: not required.
#
#openssl pkcs12 -export -out RootCA.pfx -inkey RootCA.key -in RootCA.crt
#
# get xhost.key xhost.csr:
# C: Country
# ST: State
# L: locality (city)
# O: Organization Name
# OU: Organization Unit
# CN: Common Name
#
openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"
#
# get xhost.crt certified by RootCA.pem:
# to show content:
# openssl x509 -in xhost.crt -noout -text
#
openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt
#
# get xhost.pfx, permitting to import into iis:
#
openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt
#
# import xhost.pfx in iis10 installed in xhost computer (here localhost).
#
To install openSSL for Windows, please visit https://slproweb.com/products/Win32OpenSSL.html
With all the security issues and hacking incidents popping up in the news lately, it has become fundamental to implement websites with security always turned on. CMS providers (such as Sitecore and Episerver) have begun to require secure connections, even for development environments. In most cases it isn’t feasible to buy cryptographic certificates for every developer’s local dev environment, but you can easily obtain self-signed certificates for free. These certificates are OK to be used in local environments and will cover the security requirements during the development of the solution. However, self-signed certificates should NEVER be used for production or public-facing websites.
PowerShell in Windows 10 includes the command New-SelfSignedCertificate. It provides more flexibility than the very simple «Create Self-Signed Certificate» option in IIS, and it isn’t as complicated to use as MakeCert.exe.
Below I will provide a quick overview and guide for using self-signed certificates for local sites in IIS — and avoid the «invalid certificate» warning from the web browser. Before you start, make sure you have decided on a local DNS name for your site, and that you have added that entry to your local hosts file. For this example, our local site will be named «mysite.local»
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "mysite.local" -FriendlyName "MySiteCert" -NotAfter (Get-Date).AddYears(10)
This will create a self-signed certificate specific for mysite.local that is valid for 10 years. You can modify the number of years by changing the value in the AddYears function.
-
Locate the created certificate (in this example look under the Issued To column «mysite.local», or under the Friendly Name column «MySiteCert»)
-
With the right mouse button, drag and drop the certificate to the location opened in the previous step
- Select «Copy Here» in the popup menu
Open IIS, navigate to your site, and add an https binding to it. Make sure you enter the host name, check the «Require Server Name Indication» checkbox, and select the SSL certificate «MySiteCert» (or the friendly name you entered during the certificate creation). Test your site by opening a web browser and entering «https://mysite.local/», and you shouldn’t be getting any invalid certificate warnings.
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Subject "*.example.local" -DnsName "example.local", "*.example.local" -FriendlyName "LocalStarCert" -NotAfter (Get-Date).AddYears(10)
And perform the same steps as the single domain certificate. In IIS, use the same certificate in the https binding for each site.
В этой статье объясняется, как создать самоподписанный сертификат SSL с помощью инструмента openssl
.
Что такое самоподписанный сертификат SSL?
Самозаверяющий сертификат SSL — это сертификат, подписанный лицом, создавшим его, а не доверенным центром сертификации. Самозаверяющие сертификаты могут иметь тот же уровень шифрования, что и доверенный сертификат SSL, подписанный ЦС.
Веб-браузеры не распознают самозаверяющие сертификаты как действительные. При использовании самозаверяющего сертификата веб-браузер показывает посетителю предупреждение о том, что сертификат веб-сайта не может быть проверен.
Обычно самозаверяющие сертификаты используются для целей тестирования или внутреннего использования. Вы не должны использовать самозаверяющий сертификат в производственных системах, подключенных к Интернету.
Подготовка
Набор инструментов OpenSSL необходим для создания самозаверяющего сертификата.
Чтобы проверить, установлен ли пакет openssl
в вашей системе Linux, откройте терминал, введите openssl version
и нажмите Enter. Если пакет установлен, система распечатает версию OpenSSL, иначе вы увидите что-то вроде openssl command not found
.
Если пакет openssl не установлен в вашей системе, вы можете установить его с помощью диспетчера пакетов вашего дистрибутива:
-
Ubuntu и Debian
sudo apt install openssl
-
Centos и Fedora
sudo yum install openssl
Создание самоподписанного сертификата SSL
Чтобы создать новый самоподписанный сертификат SSL, используйте команду openssl req
:
openssl req -newkey rsa:4096
-x509
-sha256
-days
-nodes
-out example.crt
-keyout example.key
Давайте разберем команду и поймем, что означает каждая опция:
-newkey rsa:4096
— Создает новый запрос сертификата и 4096-битный ключ RSA. По умолчанию — 2048 бит.-
-x509
— Создает сертификат X.509. -
-sha256
— использовать 265-битный SHA (алгоритм безопасного хеширования). -
-days 3650
— количество дней, в течение которых сертификат должен быть сертифицирован. 3650 — это десять лет. Вы можете использовать любое положительное целое число. -
-nodes
— создает ключ без ключевой фразы. -
-out example.crt
— указывает имя файла, в которое будет записан вновь созданный сертификат. Вы можете указать любое имя файла. -
-keyout example.key
— указывает имя файла, в которое будет-keyout example.key
только что созданный закрытый ключ. Вы можете указать любое имя файла.
Для получения дополнительной информации о параметрах команды openssl req
посетите страницу документации OpenSSL req.
Как только вы нажмете Enter, команда сгенерирует закрытый ключ и задаст вам ряд вопросов. Предоставленная вами информация используется для создания сертификата.
Generating a RSA private key
......................................................................++++
........++++
writing new private key to 'example.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Введите запрошенную информацию и нажмите Enter
.
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Alabama
Locality Name (eg, city) []:Montgomery
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Linuxize
Organizational Unit Name (eg, section) []:Marketing
Common Name (e.g. server FQDN or YOUR name) []:linuxize.com
Email Address []:[email protected]
Сертификат и закрытый ключ будут созданы в указанном месте. Используйте команду ls, чтобы убедиться, что файлы были созданы:
ls
example.crt example.key
Это оно! Вы создали новый самоподписанный сертификат SSL.
Всегда рекомендуется создавать резервную копию нового сертификата и ключа на внешнем хранилище.
Создание самозаверяющего SSL-сертификата без запроса
Если вы хотите сгенерировать самозаверяющий сертификат SSL без запроса на какой-либо вопрос, используйте параметр -subj
и укажите всю информацию о теме:
openssl req -newkey rsa:4096
-x509
-sha256
-days
-nodes
-out example.crt
-keyout example.key
-subj
Generating a RSA private key
......................................................................++++
........++++
writing new private key to 'example.key'
-----
Поля, указанные в строке -subj
, перечислены ниже:
C=
— Название страны. Двухбуквенное сокращение ISO.-
ST=
— Название штата или провинции. -
L=
— Название населенного пункта. Название города, в котором вы находитесь. -
O=
— полное название вашей организации. -
OU=
— Организационная единица. -
CN=
— полное доменное имя.
Выводы
В этом руководстве мы показали вам, как сгенерировать самоподписанный сертификат SSL с помощью инструмента openssl. Теперь, когда у вас есть сертификат, вы можете настроить приложение для его использования.
Am I missing something? Is this the correct way to build a self-signed certificate?
It’s easy to create a self-signed certificate. You just use the openssl req
command. It can be tricky to create one that can be consumed by the largest selection of clients, like browsers and command line tools.
It’s difficult because the browsers have their own set of requirements, and they are more restrictive than the IETF. The requirements used by browsers are documented at the CA/Browser Forums (see references below). The restrictions arise in two key areas: (1) trust anchors, and (2) DNS names.
Modern browsers (like the warez we’re using in 2014/2015) want a certificate that chains back to a trust anchor, and they want DNS names to be presented in particular ways in the certificate. And browsers are actively moving against self-signed server certificates.
Some browsers don’t exactly make it easy to import a self-signed server certificate. In fact, you can’t with some browsers, like Android’s browser. So the complete solution is to become your own authority.
In the absence of becoming your own authority, you have to get the DNS names right to give the certificate the greatest chance of success. But I would encourage you to become your own authority. It’s easy to become your own authority, and it will sidestep all the trust issues (who better to trust than yourself?).
This is probably not the site you are looking for!
The site’s security certificate is not trusted!
This is because browsers use a predefined list of trust anchors to validate server certificates. A self-signed certificate does not chain back to a trusted anchor.
The best way to avoid this is:
- Create your own authority (i.e., become a CA)
- Create a certificate signing request (CSR) for the server
- Sign the server’s CSR with your CA key
- Install the server certificate on the server
- Install the CA certificate on the client
Step 1 — Create your own authority just means to create a self-signed certificate with CA: true
and proper key usage. That means the Subject and Issuer are the same entity, CA is set to true in Basic Constraints (it should also be marked as critical), key usage is keyCertSign
and crlSign
(if you are using CRLs), and the Subject Key Identifier (SKI) is the same as the Authority Key Identifier (AKI).
To become your own certificate authority, see *How do you sign a certificate signing request with your certification authority? on Stack Overflow. Then, import your CA into the Trust Store used by the browser.
Steps 2 — 4 are roughly what you do now for a public facing server when you enlist the services of a CA like Startcom or CAcert. Steps 1 and 5 allows you to avoid the third-party authority, and act as your own authority (who better to trust than yourself?).
The next best way to avoid the browser warning is to trust the server’s certificate. But some browsers, like Android’s default browser, do not let you do it. So it will never work on the platform.
The W3C’s WebAppSec Working Group is starting to look at the issue. See, for example, Proposal: Marking HTTP As Non-Secure.
How to create a self-signed certificate with OpenSSL
The commands below and the configuration file create a self-signed certificate (it also shows you how to create a signing request). They differ from other answers in one respect: the DNS names used for the self signed certificate are in the Subject Alternate Name (SAN), and not the Common Name (CN).
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# IP.1 = 127.0.0.1
# IP.2 = ::1
It’s important to put DNS name in the SAN and not the CN, because both the IETF and the CA/Browser Forums specify the practice. They also specify that DNS names in the CN are deprecated (but not prohibited). If you put a DNS name in the CN, then it must be included in the SAN under the CA/B policies. So you can’t avoid using the Subject Alternate Name.
Create a self signed certificate (notice the addition of -x509
option):
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
Create a signing request (notice the lack of -x509
option):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
Print a self-signed certificate:
openssl x509 -in example-com.cert.pem -text -noout
Print a signing request:
openssl req -in example-com.req.pem -text -noout
Configuration file (passed via -config
option)
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY
localityName = Locality Name (eg, city)
localityName_default = New York
organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company
emailAddress = Email Address
emailAddress_default = test@example.com
# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1
# IPv6 localhost
# DNS.8 = ::1
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
There are other rules concerning the handling of DNS names in X.509/PKIX certificates. Refer to these documents for the rules:
RFC 6797 and RFC 7469 are listed, because they are more restrictive than the other RFCs and CA/B documents. RFCs 6797 and 7469 do not allow an IP address, either.