从Chrome 58开始,它不再接受依赖于Common Name的自签名证书:https://productforums.google.com/forum/#!topic/chrome/zVo3M8CgKzQ;context-place=topicsearchin/chrome/category$3ACanary%7Csort :relevance%7Cspell:false

相反,它需要使用Subject Alt Name。之前,我一直在遵循有关如何生成自签名证书的指南:https://devcenter.heroku.com/articles/ssl-certificate-self效果很好,因为我需要使用server.crtserver.key文件在做。现在,我需要生成包含SAN的新证书,但是我所做的所有尝试都不适用于Chrome58。

这是我已经完成的工作:

我按照上述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文件,并将其添加到了我的系统证书中。然后,我将其设置为Always Trust

除了用于设置SAN值的配置文件外,这些与我在早期版本的Chrome中用于生成并信任自签名证书的步骤相似。

但是,在此之后,我仍然在Chrome 58中得到了ERR_CERT_COMMON_NAME_INVALID

#1 楼

我的解决方案:

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


状态:对我有用

评论


大量使用subshel​​l。我认为您可以简化一下:-config <(cat /System/Library/OpenSSL/openssl.cnf; printf'[SAN] \ nsubjectAltName = DNS:dev.mycompany.com')

– jrwren
17年4月21日在16:45

我不再收到“主题替代名称”错误,但是现在我收到有关通用名称的错误,并且将下载的证书设置为“始终信任”不起作用。有什么想法吗? @bcardarella

–rugbert
17年5月25日在20:11

随着Chrome 59的更新,证书显示如下错误:网站的证书链(net :: ERR_CERT_COMMON_NAME_INVALID)出现问题。

–严峻
17年6月17日在10:51

我将dev.company.name更改为localhost,这可用于从localhost服务本地开发站点。在macOS上,我还必须将证书添加到“钥匙串”并将SSL设置为“始终信任”。

–丹尼尔·M。
17年11月9日17:52



到目前为止,这是最简单的解决方案,不需要拧紧sslconf或安装CA。

–bp。
18年1月25日在8:57

#2 楼

在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


#3 楼

这是一个适合我的解决方案:

创建CA密钥和证书

# 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'


您已经完成!

P.S.无需创建功能齐全的CA和服务器证书对(按照上述说明),您只需在HTTP服务器配置中禁用HSTS标头即可。
这将阻止Chromium强制执行HTTPS,并允许用户单击“高级→继续执行your.url(不安全)”,而无需获取并安装自定义CA(server_rootCA.pem)证书。换句话说,必须禁用HSTS才能通过HTTP和/或不安全的HTTPS连接公开查看您的站点(请注意!)。

对于Apache2,请将以下内容添加到站点文件HTTP(端口)中80)section

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/自签名_https_cert_after_chrome_58

评论


遵循根CA权威机构的路径,该机构随后会对各个证书进行签名,这是我可以使chrome进行完全身份验证的唯一方法。还有一个优点是,我只需要让人们安装一个证书即可。谢谢

–geoff
17年4月4日在16:18

有人可以向我解释为什么这个领域的每个人似乎都使用-config <(cat server_rootCA.csr.cnf)这样的bashisms而不是仅-config server_rootCA.csr.cnf吗?

–凯撒
18 Mar 28 '18在7:49

您能否更新与可以绕过此问题的apache标头有关的答案(我不介意这仅适用于本地开发站点,因此我喜欢通用解决方案,而不必每次都生成新证书)。您能否指出这些应该在虚拟主机定义中的哪个位置。我尝试了几种替代方法,但仍然无法通过https访问网站。谢谢

– Nikos M.
18/12/18在15:51

#4 楼

有几个很棒的答案给出了如何使它工作的示例,但没有一个可以解释您尝试中哪里出错了。在某些时候,OpenSSL可能非常不直观,因此值得一读。

首先,顺便说一句,OpenSSL默认会忽略您在其中提供的任何可分辨的名称值
。配置。如果要使用它们,必须在配置中添加prompt = no
。另外,编写的命令仅生成证书
,而不是证书本身,因此-days命令不执行任何操作。

如果使用此命令生成证书请求,则您给与并检查< br结果,出现了主题替代名称:

$ 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链接中的命令生成证书并
检查结果,主题替代名称丢失:

$ 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不会将扩展从请求复制到证书。通常,证书将由CA
根据客户的请求创建/签名,并且某些扩展可能授予证书
比CA盲目信任
所希望的权力
/>请求中定义的扩展。

有多种方法告诉OpenSSL复制扩展,但是恕我直言,这不仅仅是在生成时在配置文件中提供扩展之外的工作。
证书。

如果您尝试使用现有的配置文件,将无法使用,因为
顶层标记为[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


评论


这是唯一可以帮助我理解为什么证书不带SAN的原因的解释(对于我而言,我需要在配置文件中包含x509_extensions)

–Daniel Beardsmore
18/12/10在9:54

#5 楼

具有配置功能的Bash脚本作为一个shell脚本在Bash中跨平台运行。假设为外壳设置了HOSTNAME env或提供您选择的主机名,例如self_signed_cert.sh test
set -e

if [ -z "" ]; then
  hostname="$HOSTNAME"
else
  hostname=""
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"

以上内容或多或少注入了opensl所需的最低配置文件信息。
请注意,包括额外的DNS:localhost作为SAN,可以更轻松地通过本地主机进行测试。如果您不想要,请从脚本中删除该多余的部分。
信用
bcardarella的答案很好(由于代表不足,无法评论/投票)。但是,答案使用的是特定于平台的现有openssl config文件位置...因此:

为我工作

显然,人们只需要找到openssl config文件以适合您自己的平台并替换正确的位置。
测试
要进行测试,请在test.cert.pem中将chrome://settings/certificates导入chrome的授权中,然后:
openssl s_server -key test.key.pem -cert test.cert.pem -accept 20443 -www &
openssl_pid=$!
google-chrome https://localhost:20443

并在测试后
kill $openssl_pid


评论


在某些情况下,主机名是IP地址。当前的Chrome(v80)将拒绝IP地址标记为DNS的具有SAN的证书,需要将其设置为IP:123.123.123.123(或任何IP地址)

– egerardus
20-4-1在16:20



#6 楼

我的解决方案是使主要openssl.cnf保持原样,并在最后添加一个新部分,例如[ cert_www.example.com ],其中www.example.com是我要为其创建证书的网站,然后在其中放入subjectAltName需要(以及其他任何东西)。当然,该部分可以命名为任意名称。

之后,我可以像以前一样运行openssl req命令,只需添加-extensions cert_www.example.com以获取其内容,然后添加-subj直接添加所有DN信息。

不要忘记在证书创建后和使用前通过openssl x509 -text验证证书内容。