Створення сертифікованого сертифіката cers з openssl, який працює в Chrome 58


52

Що стосується Chrome 58, він більше не приймає сертифіковані сертифікати, які покладаються на Common Name: https://productforums.google.com/forum/#!topic/chrome/zVo3M8CgKzQ ; context-place=topicsearchin/chrome/category $ 3ACanary% 7Csort: актуальність% 7Cspell: false

Натомість вимагає використання Subject Alt Name. Раніше я дотримувався цього посібника про те, як генерувати самопідписаний сертифікат: https://devcenter.heroku.com/articles/ssl-certificate- себе, який працював чудово, бо мені потрібні файли server.crtта server.keyфайли для того, що я роблю. Зараз мені потрібно генерувати нові серти, які включають, SANпроте всі мої спроби зробити це не спрацювали з Chrome 58.

Ось що я зробив:

Я дотримувався кроків у вищезгаданій статті Heroku, щоб створити ключ. Потім я написав новий конфігураційний файл OpenSSL:

[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
req_extensions      = san
extensions          = san
[ req_distinguished_name ]
countryName         = US
stateOrProvinceName = Massachusetts
localityName        = Boston
organizationName    = MyCompany
[ san ]
subjectAltName      = DNS:dev.mycompany.com

Потім генерується команда server.crtза допомогою наступної команди:

openssl req \
-new \
-key server.key \
-out server.csr \
-config config.cnf \
-sha256 \
-days 3650

Я на Mac, тому я відкрив server.crtфайл із Keychain, додав його до моїх системних сертифікатів. Потім я встановив це Always Trust.

За винятком конфігураційного файлу для встановлення значення SAN, це були подібні кроки, які я використовував у попередніх версіях Chrome для створення та довіри cert, який підписує сам.

Однак після цього я все-таки отримую ERR_CERT_COMMON_NAME_INVALIDв Chrome 58.

Відповіді:


62

Моє рішення:

openssl req \
    -newkey rsa:2048 \
    -x509 \
    -nodes \
    -keyout server.key \
    -new \
    -out server.crt \
    -subj /CN=dev.mycompany.com \
    -reqexts SAN \
    -extensions SAN \
    -config <(cat /System/Library/OpenSSL/openssl.cnf \
        <(printf '[SAN]\nsubjectAltName=DNS:dev.mycompany.com')) \
    -sha256 \
    -days 3650

Статус: працює для мене


2
велике використання підшару. Я думаю, ви можете трохи спростити це:-config <(cat /System/Library/OpenSSL/openssl.cnf ; printf '[SAN]\nsubjectAltName=DNS:dev.mycompany.com')
jrwren

1
Я більше не отримую помилку Name Subt Alt Name, але тепер я отримую помилку щодо загальної назви, і встановити завантажений cert на "завжди довіряти" не працює. Будь-які думки? @bcardarella
rugbert

2
Під час оновлення до Chrome 59 у сертифікаті відображається така помилка: Є проблеми з ланцюжком сертифікатів сайту (нетто: ERR_CERT_COMMON_NAME_INVALID).
Сувора

1
Я змінив dev.company.nameдо localhostі це працювало для обслуговування місцевого розвитку сайту з локального хоста. На macOS мені також довелося додати сертифікат до Keychain і встановити SSL на "Завжди довіряти".
Даніель М.

1
Це, безумовно, найпростіше рішення і не вимагає накручування sslconf або встановлення CA.
bp.

16

У Windows збережіть цей скрипт у папці SSL як makeCERT.bat. Він створить ці файли: example.cnf, example.crt, example.key

@echo off

REM IN YOUR SSL FOLDER, SAVE THIS FILE AS: makeCERT.bat
REM AT COMMAND LINE IN YOUR SSL FOLDER, RUN: makecert
REM IT WILL CREATE THESE FILES: example.cnf, example.crt, example.key
REM IMPORT THE .crt FILE INTO CHROME Trusted Root Certification Authorities
REM REMEMBER TO RESTART APACHE OR NGINX AFTER YOU CONFIGURE FOR THESE FILES

REM PLEASE UPDATE THE FOLLOWING VARIABLES FOR YOUR NEEDS.
SET HOSTNAME=example
SET DOT=com
SET COUNTRY=US
SET STATE=KS
SET CITY=Olathe
SET ORGANIZATION=IT
SET ORGANIZATION_UNIT=IT Department
SET EMAIL=webmaster@%HOSTNAME%.%DOT%

(
echo [req]
echo default_bits = 2048
echo prompt = no
echo default_md = sha256
echo x509_extensions = v3_req
echo distinguished_name = dn
echo:
echo [dn]
echo C = %COUNTRY%
echo ST = %STATE%
echo L = %CITY%
echo O = %ORGANIZATION%
echo OU = %ORGANIZATION_UNIT%
echo emailAddress = %EMAIL%
echo CN = %HOSTNAME%.%DOT%
echo:
echo [v3_req]
echo subjectAltName = @alt_names
echo:
echo [alt_names]
echo DNS.1 = *.%HOSTNAME%.%DOT%
echo DNS.2 = %HOSTNAME%.%DOT%
)>%HOSTNAME%.cnf

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout %HOSTNAME%.key -days 3560 -out %HOSTNAME%.crt -config %HOSTNAME%.cnf

13

Ось рішення, яке працює для мене:

Створіть ключ CA та cert

# openssl genrsa -out server_rootCA.key 2048
# openssl req -x509 -new -nodes -key server_rootCA.key -sha256 -days 3650 -out server_rootCA.pem

Створіть server_rootCA.csr.cnf

# server_rootCA.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=DE
ST=Berlin
L=NeuKoelln
O=Weisestrasse
OU=local_RootCA
emailAddress=ikke@server.berlin
CN = server.berlin

Створіть конфігураційний файл v3.ext

# v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = server.berlin

Створіть серверний ключ

# openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server_rootCA.csr.cnf )

Створіть серверну серт

# openssl x509 -req -in server.csr -CA server_rootCA.pem -CAkey server_rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext

Додайте сертифікат і ключ до файлу сайту Apache2, розділу HTTPS (порт 443)

SSLCertificateFile    /etc/apache2/ssl/server.crt
SSLCertificateKeyFile    /etc/apache2/ssl/server.key

Скопіюйте server_rootCA.pem з сервера на свій апарат ..

# scp you@server.berlin:~/server_rootCA.pem .

.. і додайте його до браузера Chromium

Chromium -> Setting -> (Advanced) Manage Certificates -> Import -> 'server_rootCA.pem'

ВСЕ ВСЕ РОБИТИ!

PS Замість створення функціональної пари сертифікатів CA та сервера (згідно інструкцій вище) ви можете просто відключити заголовки HSTS у конфігурації HTTP-сервера. Це не дасть Chromium застосувати HTTPS і дозволить користувачам натискати «Додатково → перейти до вашого.url (небезпечно)» без необхідності отримання та встановлення власного сертифіката CA (server_rootCA.pem). Іншими словами - відключення HSTS дозволить публічно переглядати ваш сайт через HTTP та / або небезпечне з'єднання HTTPS (будьте уважні!).

Для Apache2 додайте наступне в файл-файл, розділ HTTP (порт 80)

Header unset Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=0;includeSubDomains"

Тестовано на Debian / Apache2.4 + Debian / Chromium 59

https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58


Перехід маршруту кореневого авторитету CA, який пізніше підписує окремі certs, - це єдиний спосіб, за яким я міг отримати хром для повного підтвердження автентичності; також має перевагу в тому, що мені потрібно було лише змусити людей встановити один серт. Спасибі
geoff

4
Чи можете мені хтось пояснити, чому, здається, всі в цій галузі використовують башизми, -config <( cat server_rootCA.csr.cnf )а не просто -config server_rootCA.csr.cnf?
Цезар

Чи можете ви, будь ласка, оновити свою відповідь щодо заголовків apache, які можуть обійти проблему (я не заперечую, що це стосується лише локальних сайтів для розробки, і я хотів би зробити загальне рішення без необхідності щоразу створювати нові сертифікати). Чи можете ви вказати, де всередині визначення віртуального хоста вони повинні перейти. Я спробував декілька альтернатив і досі не можу отримати доступ до сайтів через https. Спасибі
Нікос М.

12

Є кілька чудових відповідей, які наводять приклади, як це зробити, але жоден, що пояснює, де все пішло не так у вашій спробі. OpenSSL може бути досить інтуїтивно зрозумілим, тому варто пройтись.

По-перше, як сторону, OpenSSL за замовчуванням ігнорує будь-які виділені значення імен, які ви надаєте в конфігурації. Якщо ви хочете їх використовувати, ви повинні додати їх prompt = no у конфігурацію. Крім того, написана команда створює лише запит на сертифікат, а не сам сертифікат, тому -daysкоманда нічого не робить.

Якщо ви генеруєте свій запит на сертифікат за допомогою цієї команди, яку ви дали та перевіряєте результат, ім'я Alt Subject присутнє:

$ openssl req -new -key server.key -out server.csr -config config.cnf -sha256
$ openssl req -text -noout -in server.csr
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:dev.mycompany.com
    Signature Algorithm: sha256WithRSAEncryption
         ...

Але тоді, якщо ви генеруєте сертифікат за допомогою команди у посилання heroku та перевіряєте результат, ім'я Alt Subject відсутнє:

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
$ openssl x509 -text -noout -in server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            89:fd:75:26:43:08:04:61
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Validity
            Not Before: Jan 21 04:27:21 2018 GMT
            Not After : Jan 21 04:27:21 2019 GMT
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         ...

Причина полягає в тому, що за замовчуванням OpenSSL не копіює розширення з запиту до сертифіката. Зазвичай сертифікат створюється / підписується ЦО на основі запиту замовника, і деякі розширення можуть надати сертифікату більше енергії, ніж ЦС планував, якщо вони сліпо довіряти розширенням, визначеним у запиті.

Існують способи сказати OpenSSL скопіювати розширення, але для IMHO це більше роботи, ніж просто надання розширень у конфігураційний файл, коли ви генеруєте сертифікат.

Якщо ви намагалися використовувати наявний конфігураційний файл, він не працюватиме, оскільки розділ верхнього рівня позначений, [req]тому ці налаштування стосуються лише команди req, а не команди x509. Не обов’язково мати маркер розділу верхнього рівня, тому ви можете просто видалити цей перший рядок, і тоді він буде добре працювати як для генерування запитів, так і для сертифікату.

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt -extfile config.cnf

Крім того, ви можете використовувати -x509аргумент reqкоманди, щоб створити самопідписаний сертифікат в одній команді, а не спочатку створити запит, а потім сертифікат. У цьому випадку не потрібно видаляти [req]рядок розділу, оскільки цей розділ читається та використовується командою req.

$ openssl req -x509 -sha256 -days 365 -key server.key -out server.crt -config config.cnf

Для резюме, ось модифікований файл конфігурації, який використовується у наведених вище командах:

default_bits        = 2048
distinguished_name  = dn
x509_extensions     = san
req_extensions      = san
extensions          = san
prompt              = no
[ dn ]
countryName         = US
stateOrProvinceName = Massachusetts
localityName        = Boston
organizationName    = MyCompany
[ san ]
subjectAltName      = DNS:dev.mycompany.com

2
Це єдине пояснення, яке допомогло мені зрозуміти, чому сертифікат вийшов без SAN (у моєму випадку мені потрібно було включити x509_extensions у конфігураційний файл)
Daniel Beardsmore

2

Моє рішення полягає в тому, щоб зберегти головне openssl.cnfтаким, яким він є, і лише наприкінці додати новий розділ, наприклад, [ cert_www.example.com ]де www.example.com - веб-сайт, для якого я хочу створити сертифікат, і в ньому покласти subjectAltNameпотрібне мені (і будь-що інше). Звичайно, в розділі можна назвати все, що завгодно.

Після цього я можу запустити openssl reqкоманду, як і раніше, просто додавши -extensions cert_www.example.comдля того, щоб її вміст був зібраний, і я додав, -subjщоб безпосередньо додати всю інформацію про DN.

Не забудьте перевірити вміст сертифікату після його створення та перед його використанням, с openssl x509 -text


1

Сценарій Bash з конфігурацією, запеченою в

Як сценарій оболонки, який повинен працювати на платформах з bash. Передбачає HOSTNAMEнабір ENV для оболонки або введення імені хосту за вашим вибором, наприкладself_signed_cert.sh test

set -e

if [ -z "$1" ]; then
  hostname="$HOSTNAME"
else
  hostname="$1"
fi

local_openssl_config="
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = san_self_signed
[ req_distinguished_name ]
CN=$hostname
[ san_self_signed ]
subjectAltName = DNS:$hostname, DNS:localhost
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
extendedKeyUsage = serverAuth, clientAuth, timeStamping
"

openssl req \
  -newkey rsa:2048 -nodes \
  -keyout "$hostname.key.pem" \
  -x509 -sha256 -days 3650 \
  -config <(echo "$local_openssl_config") \
  -out "$hostname.cert.pem"
openssl x509 -noout -text -in "$hostname.cert.pem"

Вищезазначені більш-менш вводить необхідну інформацію про мінімальний конфігураційний файл openssl.

Зауважте, додається додатково DNS:localhostяк SAN, щоб легше проходити тестування через localhost. Видаліть цей зайвий біт із сценарію, якщо ви цього не хочете.

Кредит

Відповідь bcardarella чудова (не можу коментувати / голосувати через недостатню відповідь). Однак у відповіді використовується існуюче місце розташування файлу configs opensl, яке залежить від платформи ... отже:

Працює для мене

Очевидно, що потрібно просто знайти файл configs configs для власної заданої платформи та замінити правильне розташування.

Тест

Щоб перевірити спосіб, імпортуйте test.cert.pemдо повноважень компанії Chrome chrome://settings/certificatesі:

openssl s_server -key test.key.pem -cert test.cert.pem -accept 20443 -www &
openssl_pid=$!
google-chrome https://localhost:20443

І після тестування

kill $openssl_pid
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.