Firefox 54 прекратил доверять самоподписанным сертификатам
С недавним обновлением Firefox 54 мой самоподписанный SSL-сертификат localhost
перестает доверять.
Я использую скрипт Firefox AutoConfigure для установки этого сертификата, и этот метод успешно работает уже несколько лет. Firefox использует свое собственное хранилище сертификатов, cert8.db
которое содержит сертификат, проверено с помощью настроек Firefox, Advanced, Certificates, View Certificates, Authorities.
Это воспроизводится как на MacOS, так и на Windows. Я приложил образец сертификата для справки. Это идентично тому, который мы установили.
Что изменилось в Firefox 54? Я просмотрел журнал изменений и не могу найти ничего конкретного, как он доверяет сертификатам.
Изменить: Ссылка на ошибку Firefox, которая, скорее всего, внесла это изменение: firefox
#1294580
-----BEGIN CERTIFICATE-----
MIID/DCCAuSgAwIBAgIEDZj+fTANBgkqhkiG9w0BAQsFADCBmjELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAk5ZMRIwEAYDVQQHEwlDYW5hc3RvdGExGzAZBgNVBAoTElFa
IEluZHVzdHJpZXMsIExMQzEbMBkGA1UECxMSUVogSW5kdXN0cmllcywgTExDMRww
GgYJKoZIhvcNAQkBFg1zdXBwb3J0QHF6LmlvMRIwEAYDVQQDEwlsb2NhbGhvc3Qw
HhcNMTcwMjEyMDMzMjEwWhcNMzcwMjEyMDMzMjEwWjCBmjELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAk5ZMRIwEAYDVQQHEwlDYW5hc3RvdGExGzAZBgNVBAoTElFaIElu
ZHVzdHJpZXMsIExMQzEbMBkGA1UECxMSUVogSW5kdXN0cmllcywgTExDMRwwGgYJ
KoZIhvcNAQkBFg1zdXBwb3J0QHF6LmlvMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCemwdWhvytOwhsRyEo/9ck3nKP
oBvMdkaiXKbMWlYZfYyb/EsJzw/LiEqGGhflWjneQLcgq0nuTtRaA9cm/vgPtVRX
OHewJeYBI2C4avJyjdFfQYHJKxuLi3nwmZ5JwcDm04H6SADwdyQuYB4AFr32uY5D
3id0gyDV+EX9sSOPThtdBpEbaBcFmAdAGdQUCzSJyi4Yu6UkIs7OPBHp9lOvm8VQ
r6ZVnqdFEXmxgpgMS0sQwDwZnBB3hFcVmE/sYy+2gV/h+yvRUjgqwC/SoLh9f4D0
eG19E3OEmsSyFM9K2Wl4ltOE/Aq1KFm7dPw34nDKxYcVDpm6JczWycbCi4zjAgMB
AAGjSDBGMCUGA1UdEQQeMByCCWxvY2FsaG9zdIIPbG9jYWxob3N0LnF6LmlvMB0G
A1UdDgQWBBT3Qs6/qQSmunLIGKQxz3GBO+RgIzANBgkqhkiG9w0BAQsFAAOCAQEA
lVI3sWr6wTtVtc7gsV9Kk99xNOUm5W2kp/Ot5CHvUIw68Ar1WIiouWT9BbjkvFc+
QpbtqKhluTdHI1/JP44r7A8qMApyYQLhw3AS/WTzRoOBOECJk3hYgGBIxAaoqvKY
HKCOULTqkoX8pgNhYobebn/BpeoSvXW+oxT21y7ElE01eMtrLsqXKaN5FODxVzJq
7jatxCaRZCy2Ki3R0cB5ZMIVvWSDeT1TLgh5UKWdldNsTdTNhbQSdm8ayU0uj4fH
tKqwh9lKvrBJiawghmADjZjeNEQzIJfjznF/soqVZnRNZO/phDH327lDE2UcD1IN
k4BqNRJmz5lrQeYz8GcfYA==
-----END CERTIFICATE-----
Ответы
Ответ 1
Чтобы имитировать требования CA-цепи, установленные Firefox 54, требуется следующее:
- Keypair, помеченный как Root-CA, способный генерировать SSL-сертификат.
- Вторая ключевая пара, обозначенная для SSL, которая получает прикованный сертификат от Root-CA
Чтобы проиллюстрировать, как это делается с Java keytool
включая шаги для создания частных хранилищ ключей:
# Create a Root-CA private keystore capable of issuing SSL certificates
keytool -genkeypair -noprompt -alias my-ca -keyalg RSA -keysize 2048 -dname CN=localhost -validity 3650 -keystore .\my-ca.jks -storepass pass77 -keypass pass77 -ext ku:critical=cRLSign,keyCertSign -ext bc:critical=ca:true,pathlen:1
# Export the Root-CA certificate, to be used in the final SSL chain
keytool -exportcert -alias my-ca -keystore .\my-ca.jks -storepass pass77 -keypass pass77 -file .\my-ca.crt -rfc -ext ku:critical=cRLSign,keyCertSign -ext bc:critical=ca:true,pathlen:1
# Create a container SSL private keystore (external localhost.foo.bar dns entry optional:IE11 domain intranet policy)
keytool -genkeypair -noprompt -alias my-ssl -keyalg RSA -keysize 2048 -dname CN=localhost -validity 3650 -keystore .\my-ssl.jks -storepass pass77 -keypass pass77 -ext ku:critical=digitalSignature,keyEncipherment -ext eku=serverAuth,clientAuth -ext san=dns:localhost,dns:localhost.foo.bar -ext bc:critical=ca:false
# Create a certificate signing request (CSR) from our SSL private keystore
keytool -certreq -keyalg RSA -alias my-ssl -file .\my-ssl.csr -keystore .\my-ssl.jks -keypass pass77 -storepass pass77
# Issue an SSL certificate from the Root-CA private keystore in response to the request (external localhost.foo.bar dns entry optional)
keytool -keypass pass77 -storepass pass77 -validity 3650 -keystore .\my-ca.jks -gencert -alias my-ca -infile .\my-ssl.csr -ext ku:critical=digitalSignature,keyEncipherment -ext eku=serverAuth,clientAuth -ext san=dns:localhost,dns:localhost.foo.bar -ext bc:critical=ca:false -rfc -outfile .\my-ssl.crt
# Import Root-CA certificate into SSL private keystore
keytool -noprompt -import -trustcacerts -alias my-ca -file my-ca.crt -keystore my-ssl.jks -keypass pass77 -storepass pass77
# Import an SSL (chained) certificate into keystore
keytool -import -trustcacerts -alias my-ssl -file my-ssl.crt -keystore my-ssl.jks -keypass pass77 -storepass pass77 -noprompt
Как только это будет сделано, только Firefox Root-CA должен быть доверен Firefox и может быть импортирован с использованием графического интерфейса или с помощью сценария AutoConfig.
Сервер SSL должен быть перезапущен с использованием нового закрытого хранилища ключей SSL, которое будет содержать цепочку доверия для работы через SSL.
Поскольку my-ssl.jks
содержит всю цепочку доверия my-ca.jks
, my-ca.crt
, my-ssl.crt
и my-ssl.csr
можно безопасно удалить (при условии, что my-ca.crt
был импортирован должным образом)
Ответ 2
Вдохновленный ответом @tresf и основанный в основном на blogpost Как создать свой собственный центр сертификации SSL для локальной разработки HTTPS Брэдом Туеснаром, я создал набор команд с помощью openssl
.
# Generate the root key
openssl genrsa -des3 -out myCA.key 2048
# Generate a root-certificate based on the root-key
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
# Generate a new private key
openssl genrsa -out example.com.key 2048
# Generate a Certificate Signing Request (CSR) based on that private key
openssl req -new -key example.com.key -out example.com.csr
# Create a configuration-file
echo \
"authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
"> example.com.conf
# Create the certificate for the webserver to serve
openssl x509 -req -in example.com.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial \
-out example.com.crt -days 1825 -sha256 -extfile example.com.conf
Как использовать эти файлы
1. Пусть вашему CA доверяют ваш браузер /keychain
Добавьте myCa.pem
в свой браузер /keychain, чтобы доверять сертификатам, подписанным вашим новым корневым сертификатом
2. Подпишите запросы с вашим сертификатом
Добавьте example.com.crt
и example.com.key
в конфигурацию вашего веб-сервера, чтобы подписывать запросы в ваш домен.
Ответ 3
Как сообщают @tresf и @Zombaya, Firefox требует два сертификата:
- Сертификат полномочий
- Сертификат разработки
Сертификат полномочий используется для подписи сертификата разработки. Сертификат разработки связан с портом HTTP. Веб-сервер прослушивает этот порт для запросов.
Среда разработки Windows
Другие ответы объясняют, что делать в среде Java и Unix. Вот что я делаю в среде разработки Windows. Это создает сертификаты, которым доверяют Firefox, Chrome и Internet Explorer:
Переопределите DNS с записью в файле C:\Windows\System32\drivers\etc\hosts.
127.0.0.1 dev.brainstorm.com
Создайте сертификаты полномочий и разработки и сохраните их в хранилище сертификатов локального компьютера с помощью PowerShell. Замените "Мозговой штурм" на название вашей компании и запись в DNS. Запустите PowerShell в качестве администратора.
# Create authority certificate.
# TextExtension adds the Server Authentication enhanced key usage and the CA basic contraint.
$authorityCert = New-SelfSignedCertificate '
-Subject "CN=Brainstorm CA,OU=IT,O=Brainstorm Certificate Authority,C=US" '
-KeyAlgorithm RSA '
-KeyLength 4096 '
-KeyUsage CertSign, CRLSign, DigitalSignature, KeyEncipherment, DataEncipherment '
-KeyExportPolicy Exportable '
-NotBefore (Get-Date) '
-NotAfter (Get-Date).AddYears(10) '
-HashAlgorithm SHA256 '
-CertStoreLocation "Cert:\LocalMachine\My" '
-FriendlyName "Brainstorm CA" '
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1", "2.5.29.19={critical}{text}ca=1")
# Create development certificate.
# Sign it with authority certificate.
# TextExtension adds the Server Authentication enhanced key usage.
$devCert = New-SelfSignedCertificate '
-Subject "CN=Brainstorm,OU=Application Development,O=Brainstorm,C=US" '
-DnsName dev.brainstorm.com '
-KeyAlgorithm RSA '
-KeyLength 4096 '
-KeyUsage DigitalSignature, KeyEncipherment, DataEncipherment '
-KeyExportPolicy Exportable '
-NotBefore (Get-Date) '
-NotAfter (Get-Date).AddYears(10) '
-HashAlgorithm SHA256 '
-CertStoreLocation "Cert:\LocalMachine\My" '
-FriendlyName "Brainstorm" '
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1") '
-Signer $authorityCert
# Export authority certificate to file.
$directory = "C:\Users\Erik\Documents\Temp\Certificates\"
if(!(test-path $directory))
{
New-Item -ItemType Directory -Force -Path $directory
}
$authorityCertPath = 'Cert:\LocalMachine\My\' + ($authorityCert.ThumbPrint)
$authorityCertFilename = $directory + "Authority.cer"
Export-Certificate -Cert $authorityCertPath -FilePath $authorityCertFilename
# Import authority certificate from file to Trusted Root store.
Import-Certificate -FilePath $authorityCertFilename -CertStoreLocation "Cert:\LocalMachine\Root"
# Delete authority certificate file.
Remove-Item -Path $authorityCertFilename
Предоставьте разработчику разрешение на размещение веб-сайта и услуги по определенным URL-адресам и портам (через IIS Express). Используйте стандартный порт SSL для веб-сайта, используйте другой порт для обслуживания. Зачем? IIS Express не может одновременно размещать два приложения на одном и том же порту, отличающиеся именем хоста. Они должны использовать разные порты.
netsh http add urlacl url=https://dev.brainstorm.com:443/ user="Erik"
netsh http add urlacl url=https://dev.brainstorm.com:44300/ user="Erik"
Если вам нужно удалить разрешение разработчика для размещения веб-сайта по URL-адресу:
netsh http delete urlacl url=https://dev.brainstorm.com:443/
netsh http delete urlacl url=https://dev.brainstorm.com:44300/
Перечислите сертификаты в хранилище локального компьютера.
Get-ChildItem -path "Cert:\LocalMachine\My"
Скопируйте отпечаток сертификата разработки (не сертификат органа).
Перечислите сертификаты, привязанные к портам HTTP. (IIS Express настраивает порты 44300 - 44399 с собственным сертификатом SSL).
netsh http show sslcert
Скопируйте идентификатор приложения (он одинаковый для всех портов IIS Express 44300 - 44399). Замените веб-сайт и сервисные порты, уже связанные с IIS Express, нашим сертификатом разработки (certhash - это отпечаток сверху). Возможно, сначала вам нужно запустить netsh, а затем ввести команду http, а затем ввести команду sslcert....
netsh http add sslcert hostnameport=dev.brainstorm.com:443 certhash=FE035397A4C44AB591A1D9D4DC0B44074D0F95BA appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certstore=my
netsh http add sslcert hostnameport=dev.brainstorm.com:44300 certhash=FE035397A4C44AB591A1D9D4DC0B44074D0F95BA appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certstore=my
Если вам нужно отменить сертификаты из портов HTTP:
netsh http delete sslcert hostnameport=dev.brainstorm.com:443
netsh http delete sslcert hostnameport=dev.brainstorm.com:44300
В Visual Studio настройте файл службы launchSettings.json (в папке "Свойства"):
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://dev.brainstorm.com:44300/",
"sslPort": 44300
}
},
"profiles": {
"Default": {
"commandName": "IISExpress",
"use64Bit": true
}
}
}
В Visual Studio настройте файл веб-сайта launchSettings.json (в папке "Свойства"):
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://dev.brainstorm.com/",
"sslPort": 443
}
},
"profiles": {
"Default": {
"commandName": "IISExpress",
"launchBrowser": true,
"use64Bit": true
}
}
}
Настройте IIS Express (в скрытой папке.vs/config):
<sites>
<site name="Website" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:443:dev.brainstorm.com" />
</bindings>
</site>
<site name="Service" id="2">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\IIS Service" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:44300:dev.brainstorm.com" />
</bindings>
</site>
<siteDefaults>
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
</siteDefaults>
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
В Firefox перейдите к about: config и установите для параметра security.enterprise_roots.enabled значение true.
Ответ 4
То, что вы, вероятно, захотите сделать, - это создать еще один самозаверяющий сертификат с тем же предметом, эмитентом и открытым ключом, которым вы доверяете. Однако вместо расширений конечных сущностей вы хотите указать, что это сертификат CA с "basicConstraints: cA" и что он может выдавать сертификаты с помощью "keyUsage: cRLSign, keyCertSign". Также может быть хорошей идеей добавить расширение nameConstraints, чтобы ограничить его только применимым к определенному набору доменов. Если вы добавите этот сертификат в базу данных доверия Firefox, все должно работать по-прежнему.