创建有效的自签名 SSL 证书是一场噩梦

创建有效的自签名 SSL 证书是一场噩梦

我有一个需要安装 SSL 的内部网服务器。

这是openssl.cnf

[ req ]
default_md              = sha256
distinguished_name      = req_distinguished_name
attributes              = req_attributes
req_extensions          = req_ext
#prompt = no

[ req_distinguished_name ]
countryName                     = US
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = CHICAGO
localityName                    = CHICAGO
0.organizationName              = MY COMPANY
organizationalUnitName          = IOS DEVELOPMENT
commonName                      = server2.myserver.local
commonName_max                  = 64
emailAddress                    = [email protected]
emailAddress_max                = 64

[ req_attributes ]
challengePassword               = password
challengePassword_min           = 4
challengePassword_max           = 20

[ req_ext ]
subjectAltName = @alt_names
extendedKeyUsage = serverAuth

[alt_names]
DNS.1   = server2.myserver.local
DNS.2   = myserver.local

这是我用来创建它的命令。

  1. 生成根 CA 密钥

    openssl genrsa -des3 -out rootCA.key 4096
    

2.这将生成根 CA 证书

openssl req \
    -x509 -new -nodes \
    -key rootCA.key -sha256 \
    -days 825 \
    -out rootCA.crt \
    -subj /CN=server2.myserver.local \
    -reqexts SAN \
    -extensions SAN \
    -config <(cat ./openssl.cnf \
        <(printf '[SAN]\nsubjectAltName=DNS:server2.myserver.local')) \
    -extensions 'req_ext'
  1. 生成证书密钥

    openssl genrsa -out mydomain.com.key 4096
    
  2. 生成证书

    openssl req -new -sha256 -key  mydomain.com.key \
     -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=server2.myserver.local" \
     -reqexts SAN \
     -config <(cat ./openssl.cnf \
         <(printf "\n[SAN]\nsubjectAltName=DNS:server2.myserver.local,DNS:myserver.local")) \
     -out mydomain.com.csr
    
  3. 将 CA 证书转换为 p12

    openssl pkcs12 -export -out ca.p12 -inkey rootCA.key -in rootCA.crt  
    
  4. 将证书转换为 p12

    openssl pkcs12 -export -out certificate.p12 -inkey mydomain.com.key -in mydomain.com.crt
    

然后我在我的 IIS 服务器和设备上安装ca.p12它。certificate.p12

当我尝试访问server2.myserver.local

我明白了

在此处输入图片描述

我到底该如何做呢?

答案1

我想说的是,您的根 CA 证书完全错误。CA 证书与终端主机 TLS 证书有很大不同 - 您不能对两者使用相同的配置。

  • 不要将服务器的域放在主题中 - 这毫无用处。如果是 CA,则应该有CN=My internal CA或类似的东西。

  • 添加basicConstraints扩展。必须说明该证书是 CA。

  • 添加正确的keyUsage。您需要有“keyCertSign”和(仅出于完整性考虑)“cRLSign”。

  • 不要添加subjectAltName。该证书是为颁发机构/发行者颁发的,不是为服务器颁发的!

  • 不要添加extendedKeyUsage。它有时用于限制 CA 可以颁发的证书,但最好从一开始就不要使用这种复杂性。

  • 添加 是个好主意subjectKeyIdentifier,以防您以后最终拥有多个具有相同主题 DN 的内部 CA。(通常,CA DN 必须是唯一的,但使用 SKI/AKI 可以放宽这一点。)

因此,您应该有一个看起来更像这样的“CA”配置文件(并且停止通过命令行添加 SAN 和其他东西 - 这就是配置的用途):

[ req ]
default_md              = sha256
distinguished_name      = req_distinguished_name
req_extensions          = req_ext

[ req_dn ]
countryName             = US
stateOrProvinceName     = Chicago
organizationName        = Company Name
organizationalUnitName  = iOS development
commonName              = Internal development CA

[ req_ext ]
basicConstraints        = critical, CA:TRUE
keyUsage                = keyCertSign, cRLSign
subjectKeyIdentifier    = hash

而最终实体证书(TLS 服务器)应该具有以下扩展:

...
[ req_ext ]
basicConstraints        = CA:FALSE
keyUsage                = digitalSignature, keyEncipherment
extendedKeyUsage        = serverAuth
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid, issuer
subjectAltName          = DNS:server2.myserver.local

然后,我在我的 IIS 服务器和设备上安装 ca.p12 和 certificate.p12。

不要在您的设备上安装CA的私钥!不要在服务器上安装它。你应该安装仅有的CA 证书rootCA.crt(公共部分),仅此而已。


我最后的建议是:不要浪费时间尝试使用 raw 制作 CA。openssl而是使用简易RSA(OpenVPN 自带的),或者使用西卡(图形化 Linux 应用程序),或者使用可能有几十个已经编写并测试过的程序。

相关内容