我使用以下脚本创建根 CA 和证书:
#! /bin/bash
set -e
base_folder="$HOME/.acme-development-certs"
start_dir=$PWD
if test -f "$base_folder/leaf_cert/acme.pem"; then
echo "ACME development certs already created: skipping CA and cert creation."
exit 0
fi
mkdir -p $base_folder
cd $base_folder
# create root cert
mkdir -p root_ca/certs root_ca/crl root_ca/newcerts root_ca/private
echo 1000 > root_ca/serial
touch root_ca/index.txt root_ca/index.txt.attr
echo '
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = root_ca # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
private_key = $dir/private/ca.key # The private key
nameopt = default_ca
certopt = default_ca
policy = policy_match
default_days = 3650
default_md = sha512
copy_extensions = copy
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
utf8 = yes
string_mask = utf8only
x509_extensions = v3_req
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
CN = ACME Development Root CA
O = ACME
OU = ACME Engineering
[v3_req]
basicConstraints = critical,CA:TRUE
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
' > root_ca/openssl.conf
openssl genrsa -out root_ca/private/ca.key 2048
openssl req -config root_ca/openssl.conf -new -x509 -days 3650 -key root_ca/private/ca.key -sha256 -extensions v3_req -out root_ca/certs/ca.crt
openssl x509 -in root_ca/certs/ca.crt -out root_ca/certs/ca.pem -outform PEM
# create leaf cert
mkdir leaf_cert
echo '
[ req ]Development
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
CN = ACME
O = ACME
OU = ACME Engineering
[ req_ext ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = acme.com
DNS.2 = *.acme.com
DNS.3 = *.sub.acme.com
DNS.4 = acme2.com
DNS.5 = *.acme2.com
DNS.6 = *.sub.acme2.com
' > leaf_cert/openssl.conf
openssl req -new -keyout leaf_cert/acme.key -out leaf_cert/acme.csr -days 3650 -nodes -newkey rsa:2048 -config leaf_cert/openssl.conf
openssl ca -batch -config root_ca/openssl.conf -keyfile root_ca/private/ca.key -cert root_ca/certs/ca.crt -out leaf_cert/acme.crt -infiles leaf_cert/acme.csr
openssl x509 -in leaf_cert/acme.crt -out leaf_cert/acme-leaf.pem -outform PEM
cat leaf_cert/acme-leaf.pem root_ca/certs/ca.pem > leaf_cert/acme.pem
# trust new CA at the OS level
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain $base_folder/root_ca/certs/ca.pem
# serve HTTPS using the new cert
NGINX_PATH="/usr/local/etc/nginx"
cp leaf_cert/acme.pem $NGINX_PATH/star_acme_com.pem
cp leaf_cert/acme.key $NGINX_PATH/star_acme_com.key
sudo brew services restart nginx
我尝试了两者的各种参数组合.cfg
,也尝试过将证书手动添加到钥匙串中,但没有任何效果:
Chrome 拒绝了它:
此网站无法提供安全连接
sub.acme.com不符合安全标准。
ERR_SSL_SERVER_CERT_BAD_FORMAT
笔记:
- Safari 和 curl 可以正常使用该证书。Firefox 有自己的 CA 列表,在我将根 CA 添加
.pem
到其内部列表的“Authorities”部分后,它就可以正常使用了。 - Nginx 配置为使用该证书
$NGINX_PATH/star_acme_com.key
,这可能不是问题,因为它可以与付费证书完美配合。 - 在 Chrome 开发工具的安全选项卡中,它显示
Certificate - valid and trusted
输出openssl x509 -noout -text -in <cert>
- 对于证书
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha512WithRSAEncryption
Issuer: CN=ACME Development Root CA, O=ACME, OU=ACME Engineering
Validity
Not Before: Jun 7 10:16:14 2019 GMT
Not After : Jun 4 10:16:14 2029 GMT
Subject: O=ACME, OU=ACME Engineering, CN=ACME
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
***
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:acme.com, DNS:*.acme.com, DNS:*.sub.acme.com, DNS:acme2.com, DNS:*.acme2.com, DNS:*.sub.acme2.com
Signature Algorithm: sha512WithRSAEncryption
***
- 对于根 CA
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 11358523417566447898 (0x9da194de4501091a)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=ACME Development Root CA, O=ACME, OU=ACME Engineering
Validity
Not Before: Jun 7 10:16:13 2019 GMT
Not After : Jun 4 10:16:13 2029 GMT
Subject: CN=ACME Development Root CA, O=ACME, OU=ACME Engineering
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
***
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
1F:50:BB:C9:85:C4:DB:71:46:E3:0E:B4:B5:48:B4:CF:10:C2:27:54
Signature Algorithm: sha256WithRSAEncryption
***
答案1
您还需要在 Keychain Access 中检查您的证书。双击您的证书,然后在“信任”部分下的弹出窗口中设置“始终信任”