Я щось пропускаю? Це правильний спосіб скласти самопідписаний сертифікат?
Створити сертифікат самопідписання легко. Ви просто використовуєте openssl req
команду. Створити такого, який може споживати найбільший вибір клієнтів, як-от браузери та інструменти командного рядка, може бути складним.
Це складно, оскільки у браузерів є свій набір вимог, і вони більш обмежуючі, ніж IETF . Вимоги, якими користуються браузери, задокументовані на форумах CA / Browser (див. Посилання нижче). Обмеження виникають у двох ключових областях: (1) довіра якоря та (2) імена DNS.
Сучасні веб-переглядачі (як, наприклад, warez, який ми використовуємо у 2014/2015), хочуть отримати сертифікат, який прив’язується до якоря довіри, і вони хочуть, щоб імена DNS були представлені певним чином у сертифікаті. І браузери активно переходять проти самопідписаних серверних сертифікатів.
Деякі веб-переглядачі не дуже легко імпортувати сертифікат сервера, який самостійно підписав. Насправді ви не можете використовувати деякі браузери, як-от браузер Android. Отже, повне рішення - стати вашим власним авторитетом.
Якщо ви не станете своїм владним органом, ви повинні отримати права імен DNS, щоб дати сертифікату найбільший шанс на успіх. Але я б закликав вас стати власною владою. Стати власною владою легко, і це обійде стороною всі питання довіри (кому краще довіряти, ніж собі?).
Це, мабуть, не той сайт, який ви шукаєте!
Сертифікат безпеки сайту не довіряється!
Це тому, що браузери використовують попередньо визначений список якорів довіри для перевірки сертифікатів сервера. Сертифікат, який підписує власний підпис, не посилається на надійний якір.
Найкращий спосіб уникнути цього:
- Створіть свій власний авторитет (тобто станьте CA )
- Створіть запит на підписання сертифіката (CSR) для сервера
- Підпишіть КСВ сервера за допомогою ключа CA
- Встановіть серверний сертифікат
- Встановіть сертифікат CA на клієнта
Крок 1. Створення власних повноважень означає лише створення сертифіката, який підписав самостійно, CA: true
та належного використання ключа. Це означає, що Суб'єкт та Емітент - це одне ціле об'єднання, CA встановлено в " Основні обмеження" істинним (його також слід позначати як критичне), використання ключа - keyCertSign
і crlSign
(якщо ви використовуєте CRL), а ідентифікатор ключа суб'єкта (SKI) - те саме, що ідентифікатор ключа авторитету (AKI).
Щоб стати власним органом сертифікації, див. * Як ви підписуєте запит на підписання сертифікату у своєму сертифікаційному органі? на стеку переповнення. Потім імпортуйте свій CA в Trust Store, який використовується браузером.
Кроки 2 - 4 - це приблизно те, що ви робите зараз для загальнодоступного сервера, коли ви зараховуєте до служб ЦС, наприклад, Startcom або CAcert . Кроки 1 і 5 дозволяють уникнути сторонніх повноважень та діяти як власні повноваження (кому краще довіряти, ніж собі?).
Наступний найкращий спосіб уникнути попередження браузера - довіряти сертифікату сервера. Але деякі браузери, як-от браузер за замовчуванням Android, не дозволяють вам це робити. Таким чином, це ніколи не буде працювати на платформі.
Випуск браузерів (та інших подібних агентів користувачів) немає довіряють сертифікатам, що підписуються самі, стане великою проблемою в Інтернеті речей (IoT). Наприклад, що буде, коли ви підключите до свого термостата або холодильника, щоб запрограмувати його? Відповідь - нічого хорошого, що стосується досвіду користувача.
Робоча група WebAppSec W3C починає розглядати це питання. Див., Наприклад, Пропозиція: Позначення HTTP як незахищеного .
Як створити самопідписаний сертифікат за допомогою OpenSSL
Наведені нижче команди та конфігураційний файл створюють сертифікат самопідписання (він також показує, як створити запит на підпис). Вони відрізняються від інших відповідей в одному відношенні: імена DNS, які використовуються для самопідписаного сертифіката, містяться в альтернативному імені суб'єкта (SAN) , а не у загальній назві (CN) .
Імена DNS розміщуються в SAN через файл конфігурації з рядком subjectAltName = @alternate_names
(немає можливості зробити це через командний рядок). Потім alternate_names
у файлі конфігурації є розділ (ви повинні налаштувати це на свій смак):
[ 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
Важливо вводити ім'я DNS в SAN, а не в CN, тому що і IETF, і форуми CA / Browser визначають цю практику. Вони також визначають, що імена DNS у CN застаріли (але не забороняються). Якщо ви вписали ім'я DNS в CN, воно повинно бути включене в SAN в рамках політики CA / B. Тому ви не можете уникнути використання альтернативного імені предмета.
Якщо ви не вводите імена DNS в SAN, сертифікат не перевірятиметься під веб-переглядачем та іншими агентами користувача, які відповідають правилам форуму CA / Browser Forum.
Пов’язано: веб-переглядачі дотримуються правил CA / Browser Forum; а не політики IETF. Це одна з причин, що сертифікат, створений за допомогою OpenSSL (який, як правило, відповідає IETF), іноді не перевіряється під веб-переглядачем (браузери дотримуються CA / B). Вони різні стандарти, вони мають різну політику видачі та різні вимоги щодо перевірки.
Створіть самопідписаний сертифікат (зверніть увагу на додавання -x509
опції):
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
Створіть запит на підписання (зауважте відсутність -x509
опції):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
Роздрукуйте самопідписаний сертифікат :
openssl x509 -in example-com.cert.pem -text -noout
Роздрукувати запит на підписання :
openssl req -in example-com.req.pem -text -noout
Файл конфігурації (передається через -config
опцію)
[ 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
Можливо, вам доведеться зробити наступне для Chrome. Інакше Chrome може скаржитися на те, що загальне ім’я недійсне ( ERR_CERT_COMMON_NAME_INVALID
) . Я не впевнений, який зв'язок між IP-адресою в SAN та CN в цьому випадку.
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
Існують інші правила щодо поводження з іменами DNS у сертифікатах X.509 / PKIX. Правила див. У цих документах:
RFC 6797 та RFC 7469 перераховані, оскільки вони є більш обмежуючими, ніж інші документи RFC та CA / B. RFCs 6797 та 7469 також не дозволяють IP-адресу.