Chrome 58'de çalışan openssl ile kendinden imzalı bir sertifika oluşturma


52

Chrome 58'den itibaren, artık geçerli olan kendinden imzalı sertifikaları kabul etmiyor Common Name: https://productforums.google.com/forum/#!topic/chrome/zVo3M8CgKzQ;context-place=topicsearchin/chrome/category $ 3ACanary% 7Cort: alaka% 7Cspell: yanlış

Bunun yerine kullanmayı gerektirir Subject Alt Name. Kendimi imzalı bir sertifikanın nasıl oluşturulacağı konusunda daha önce bu kılavuzu izlemiş oldum : https://devcenter.heroku.com/articles/ssl-certificate- kendimi server.crtve yaptığım şey için gerekli server.keydosyaları aldığım için harika çalıştı . Şimdi, SANbütün denemelerimin hepsini Chrome 58 ile birlikte yapmadım.

İşte yaptığım şey:

Anahtarı üretmek için yukarıda belirtilen Heroku makalesinde yer alan adımları takip ettim. Daha sonra yeni bir OpenSSL yapılandırma dosyası yazdım:

[ 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

Daha sonra server.crtaşağıdaki komutu ile üretti :

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

Mac'tayım, bu yüzden server.crtdosyayı Keychain ile açtım, Sistem Sertifikalarıma ekledim. Daha sonra ayarladım Always Trust.

SAN değerini ayarlamak için yapılandırma dosyası dışında bunlar, kendinden imzalı sertifika oluşturmak ve ona güvenmek için önceki Chrome sürümlerinde kullandığım adımlara benziyordu.

Ancak, bundan sonra hala ERR_CERT_COMMON_NAME_INVALIDChrome 58'e giriyorum.

Yanıtlar:


61

Çözümüm:

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

Durum: Benim için çalışıyor


2
subshell büyük kullanımı. Sanırım biraz basitleştirebilirsiniz:-config <(cat /System/Library/OpenSSL/openssl.cnf ; printf '[SAN]\nsubjectAltName=DNS:dev.mycompany.com')
jrwren

1
Artık Konu Alt Adı hatasını almıyorum, ancak şimdi ortak adla ilgili bir hata alıyorum ve indirilen sertifikayı "her zaman güven" olarak ayarlamak işe yaramıyor. Düşüncesi olan var mı? @bcardarella
rugbert

2
Chrome 59 güncellemesiyle sertifika aşağıdaki gibi bir hata gösteriyor: Sitenin sertifika zincirinde sorunlar var (net :: ERR_CERT_COMMON_NAME_INVALID).
TheHarsh

1
Değiştim dev.company.nameiçin localhostve bu localhost'tan yerel kalkınma sitesini hizmet çalıştı. MacOS'ta ayrıca sertifikayı Keychain'e eklemek ve SSL'yi "Always Trust" olarak ayarlamak zorunda kaldım.
Daniel M.

1
Bu kadar basit bir çözüm ve sslconf ile uğraşmak ya da bir CA kurmak gerektirmiyor.
B.

16

Windows'ta bu komut dosyasını makeCERT.bat olarak SSL klasörünüze kaydedin. Bu dosyaları yaratacaktır: 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

İşte benim için çalışan bir çözüm:

CA anahtarı oluşturun ve sertifika verin

# 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 oluştur

# 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 yapılandırma dosyası oluşturun

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

[alt_names]
DNS.1 = server.berlin

Sunucu anahtarı oluştur

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

Sunucu sertifikası oluştur

# 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 site dosyası, HTTPS (443 numaralı bağlantı noktası) bölümüne sertifika ve anahtar ekleyin

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

Server_rootCA.pem dosyasını sunucudan makinenize kopyalayın.

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

.. ve Chromium tarayıcısına ekleyin

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

TÜM YAPILDI!

PS İşlevsel bir CA & sunucu sertifikası çifti oluşturmak yerine (yukarıdaki talimatlara göre), HTTP sunucusu yapılandırmanızdaki HSTS başlıklarını devre dışı bırakabilirsiniz. Bu, Chromium'un HTTPS'yi zorlamasını önler ve kullanıcıların özel CA (server_rootCA.pem) sertifikanızı almak ve yüklemek zorunda kalmadan “Gelişmiş → ilerlemenizi.url (güvensiz)” e tıklamasını sağlar. Başka bir deyişle - HSTS'yi devre dışı bırakmak zorunda kalmak sitenizin genel olarak HTTP üzerinden görüntülenmesine ve / veya güvensiz HTTPS bağlantısı (dikkatli olun!) Sağlayacaktır.

Apache2 için aşağıdakileri site dosyasına, HTTP (port 80) bölümüne ekleyin.

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

Debian / Apache2.4 + Debian / Chromium 59 ile test edilmiştir

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


Daha sonra bireysel sertifikaları imzalayan bir kök CA yetkilisinin rotasına gitmek, kromu tamamen doğrulamak için tek yolum; Ayrıca, insanların yalnızca tek bir sertifika yüklemelerini sağlamak için ihtiyacım olan avantaja sahiptir. Teşekkürler
geoff

4
Birisi lütfen bana bu bölgedeki herkesin neden -config <( cat server_rootCA.csr.cnf )yerine temelleri kullandığını açıklayabilir -config server_rootCA.csr.cnfmi?
Sezar,

Sorunu atlayabilecek apache başlıklarına ilişkin cevabınızı lütfen güncelleyebilir misiniz (bunun yalnızca yerel siteler için olduğunu düşünmüyorum ve her seferinde yeni sertifikalar oluşturmak zorunda kalmadan genel bir çözüm bulabilirim). Sanal bir ana bilgisayar tanımında bunların nereye gitmesi gerektiğini işaret edebilir misiniz? Birkaç alternatif denedim ve hala https üzerinden sitelere erişemiyorum. Teşekkürler
Nikos M.

12

Bu çalışmanın nasıl sağlanacağına dair örnekler veren birkaç büyük cevap var, ancak denemenizde işlerin nerelerde yanlış gittiğini açıklayan hiçbiri yok. OpenSSL bazı zamanlar sezgisel olmayabilir, bu yüzden yürümeye değer.

İlk olarak, bir kenara, OpenSSL varsayılan olarak config içinde sağladığınız herhangi bir ayırt edici ad değerini dikkate almaz. Onları kullanmak istiyorsanız prompt = no , config ekleyin . Ek olarak, yazıldığı gibi bir komut yalnızca bir sertifikanın kendisini değil bir sertifika isteğini oluşturur , bu nedenle -dayskomut hiçbir şey yapmaz.

Sertifika isteğinizi, verdiğiniz bu komutu kullanarak oluşturup sonucu denetlerseniz, Konu Alt Adı bulunur:

$ 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
         ...

Ancak, heroku linkindeki komutu kullanarak sertifikayı oluşturup sonucu incelerseniz, Konu Alt Adı eksik:

$ 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
         ...

Bunun nedeni, varsayılan olarak OpenSSL'in uzantıları istekten sertifikaya kopyalamamasıdır. Normalde, sertifika bir müşteriden gelen bir talebe bağlı olarak bir CA tarafından oluşturulur / imzalanır ve bazı uzantılar, talepte tanımlanan uzantılara açıkça güvenmeleri gerekiyorsa, sertifikaya CA'nın hedeflediğinden daha fazla güç verebilir.

OpenSSL'e uzantıları kopyalamasını söylemenin yolları vardır, ancak IMHO, sertifikayı oluştururken uzantıları bir yapılandırma dosyasında sağlamaktan daha işe yarar.

Mevcut yapılandırma dosyanızı kullanmaya çalıştıysanız, çalışmaz, üst düzey bölüm işaretlendiğinden çalışmaz, [req]bu ayarlar yalnızca x509 komutuna değil yalnızca req komutuna uygulanır. Üst düzey bir bölüm işaretçisine sahip olmak gerekmez, bu nedenle ilk satırı kaldırabilirsiniz ve ardından hem istek hem de sertifika oluşturmak için iyi çalışır.

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

Alternatif olarak, önce bir istek ve ardından bir sertifika oluşturmak yerine, tek bir komutta kendinden imzalı bir sertifika oluşturmak -x509için reqkomutun argümanını kullanabilirsiniz . Bu durumda [req], bu bölüm req komutu tarafından okunup kullanıldığından bölüm çizgisini kaldırmak gerekli değildir .

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

Özetlemek için, yukarıdaki komutlarda kullanılan değiştirilmiş yapılandırma dosyası:

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
Sertifikanın neden SAN olmadan ortaya çıktığını anlamama yardımcı olan tek açıklama budur (benim durumumda, config dosyasına x509_extensions'ı eklemem gerekiyordu)
Daniel Beardsmore

2

Benim çözümüm main tutmaktır openssl.cnfne olduğunu ve sadece sonunda gibi yeni bir bölüm eklemek için gibi [ cert_www.example.com ]www.example.com bir sertifika oluşturmak istediğiniz web sitesi olduğu ve içinde, koymak subjectAltNameben gerekir (ve başka herhangi bir şey). Tabii ki bölüm ne istersen isimlendirilebilir.

Ondan sonra openssl reqkomutu önce çalıştığım gibi çalıştırabilirim , sadece -extensions cert_www.example.comiçeriğinin alınması için ekledim ve -subjdoğrudan tüm DN bilgilerini eklemek için ekledim.

Sertifika içeriğini oluşturulduktan sonra ve kullanmadan önce doğrulamayı unutmayın. openssl x509 -text


1

Fırında yapılandırılmış olan Bash betiği

Bash ile platformlarda çalışması gereken bir kabuk betiği olarak. HOSTNAMEKabuk için env'nin ayarlandığını varsayar veya seçtiğiniz bir ana bilgisayar adını belirtir, örneğinself_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"

Yukarıdaki az ya da çok, asgari yapılandırma dosyası bilgisi openssl ihtiyaçlarını enjekte eder.

DNS:localhostLocalhost aracılığıyla daha kolay test yapılmasını sağlamak için SAN olarak ekstra olarak dahil edildiğine dikkat edin. Eğer istemiyorsanız, bu fazladan betiği kaldırın.

Kredi

bcardarella'nın cevabı harika (yetersiz temsil nedeniyle yorum yapamam / oy kullanamıyorum). Ancak, cevap platform özel bir varolan openssl config dosyası konumu kullanır ... dolayısıyla:

Benim için çalışıyor

Açıkçası, kendi verilen platformunuz için openssl config dosyasını bulmanız ve doğru yeri kullanmanız yeterli olacaktır.

Ölçek

Test etmenin bir yolu için test.cert.pemve içindeki krom makamlarına ithalat yapın chrome://settings/certificates:

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

Ve testten sonra

kill $openssl_pid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.