OpenSSL自签名证书制作(后篇):实战及验证
本篇可以直接复制命令与配置文件来完成证书,需要配置更多细节需要去我的主页参考前篇的内容。
使用x509命令
默认使用配置文件为openssl.cnf。可以通过-config指定配置文件。
场景一:生成证书,直接用于服务器(附加需求,配置多个域名)
分析: 这个场景下,生成的证书为终端证书,非CA 。我们应该配置CA:FALSE 。因为使用的是req 命令,所以修改req下面的配置。要配置多个域名,即按照需要进行配置。
方式一:在命令中配置的大部分的请求信息:
ini
[ req ]
default_bits = 2048
x509_extensions = v3_ca ?# 配置成v3证书
string_mask = utf8only
req_extensions = v3_req ?# The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = critical,?CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
subjectAltName?= @alt_names
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
配置以后在终端执行以下命令:
openssl req -x509 -newkey rsa:2048 -nodes -keyout my_server.key -out my_server.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=my_server.cn" -set_serial 01 -config openssl.cnf -extensions v3_req
方式二:在openssl.cnf中配置请求信息
ini
[ req ]
prompt = no ??#配置为no,则不询问,直接按照req_distinguished_name的配置。
#但是如果命令中带-subj, 则以-subj配置的为准
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only
req_extensions = v3_req # 配置SAN
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = critical,?CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
[ req_distinguished_name ] ????
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName = example
organizationalUnitName = it
commonName = my_server.cn
[ req_attributes ]
配置以后在终端执行以下命令:
openssl req -x509 -newkey rsa:2048 -nodes -keyout my_server.key -out my_server.crt -days 3650 -set_serial 01 -config openssl.cnf -extensions v3_req
命令关键:
-subj 配置subject 且该命令优先于config配置文件。
-extensions v3_req 配置san ,不带该命令san配置不上。
-config 如果不指定的话,使用的是默认配置文件。
该命令为一次性生成key和crt,没有证书请求文件。也可以使用多步来生成key和证书,此处不讲解。
场景二:使用根CA,签发服务器证书
需要先生成根CA,再由根CA签终端证书。
生成根CA
根CA配置ca-openssl.cnf配置如下:
ini
[ req ]
prompt?= no ??
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only
req_extensions = v3_req
[ v3_req ]
# Extensions to add to a certificate request
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE,pathlen:0???#这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ req_distinguished_name ] ????
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName = example
organizationalUnitName = root CA
commonName = my root CA
[ req_attributes ]
生成根CA:
openssl req -x509 -new -newkey rsa:2048 -nodes -keyout my_root.key -out my_root.crt -config ca-openssl.cnf -days 3650?-extensions v3_req -set_serial 01
生成服务器证书
服务器证书配置文件openssl.cnf如下:
ini
[ req ]
prompt?= no ??
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only
req_extensions = v3_req
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = critical,CA:false
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
[ req_distinguished_name ] ????
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName ???????= example
organizationalUnitName = it
commonName = my_server.cn
[ req_attributes ]
[v3_ca]
basicConstraints = critical,CA:false
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName ?????= @alt_names
openssl genpkey -algorithm rsa -out my_server.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key my_server.key -out my_server.csr -config openssl.cnf
openssl x509 -req -CA my_root.crt -CAkey my_root.key -CAcreateserial -in my_server.csr -out my_server.crt -extensions v3_ca -extfile openssl.cnf -days 3650
命令关键:
在执行openssl req -new 生成.csr文件时,关键在于req_extensions ,即v3_req 的配置。在执行openssl x509 -req 生成.crt证书文件时,为了配置扩展项,要指定 -extensions 字段,可以重新写一个字段,我们就用v3_ca。
场景三:使用根证书,中间证书,中间证书签发服务器证书
有的时候,我们存在这种场景,即我们有多种业务都需要证书,我们可以生成根证书,然后为每种业务签发中间证书。
生成根CA
ini
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca ???#配置成v3证书
[ req_distinguished_name ]
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE ??#这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
openssl req -x509 -newkey rsa:2048 -nodes -keyout my_root.key -out my_root.crt -days 3650 ?-subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=root CA/CN=my root CA" -config openssl.cnf
生成中间证书
ini
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
[ req_distinguished_name ]
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE,pathlen:0 ??#这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:TRUE
openssl req -new -newkey rsa:2048 -nodes -keyout secondary-ca.key -out secondary-ca.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=secondary ca" -config openssl.cnf
openssl x509 -req -in secondary-ca.csr -CA my_root.crt -CAkey my_root.key -CAcreateserial -out secondary-ca.crt -extensions v3_ca -extfile openssl.cnf -days 3650
注意,生成v3证书扩展字段,需要 -extensions 和 -extfile 中v3_ca指定。
生成服务器证书
ini
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
[ req_distinguished_name ]
[ v3_ca ]
basicConstraints = critical,CA:false
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:false
openssl req -new -newkey rsa:2048 -nodes -keyout my_server.key -out my_server.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=my_server.cn " -config openssl.cnf
openssl x509 -req -in my_server.csr -CA secondary-ca.crt -CAkey secondary-ca.key -CAcreateserial -out my_server.crt -extensions v3_ca -extfile openssl.cnf -days 3650
使用ca命令
使用openssl x509 和使用openssl ca 没有本质差别,openssl ca 使用的配置文件,文件中配置固定的index.txt 和serial 文件,来记录签发过的证书,确保不会重复签发。如果把当前服务器作为专门的CA签发机构,使用openssl ca 及其关联的配置文件会更好一些。如果只是命令行临时生成一下,用openssl x509完全可以满足需求。
场景一:生成证书,直接用于服务器(附加需求,配置多个域名)
创建目录:./test/my_server
创建文件:./test/my_server/index.txt ./test/my_server/serial ./test/my_server/openssl.cnf
创建文件夹:./test/my_server/key ./test/my_server/newcerts
在./test/my_server/serial
文件中写入01
./test/my_server/openssl.cnf
内容如下:
ini
[ req ]
prompt = no
x509_extensions = v3_ca ?# 配置成v3证书
string_mask = utf8only
req_extensions = v3_req ??# The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName?= example
organizationalUnitName = it
commonName = my_server.cn
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName?= @alt_names
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:FALSE ??#这里配置为false,为终端证书。
[ ca ]
default_ca = CA_default
[ CA_default ]
dir?= ./test/my_server
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl?= $dir/crl.pem
private_key = $dir/key/my_server.key
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:false
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
openssl genpkey -algorithm rsa -out ./test/my_server/key/my_server.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ./test/my_server/key/my_server.key -out ./test/my_server/key/my_server.csr -config ./test/my_server/openssl.cnf
openssl ca -selfsign -in ./test/my_server/key/my_server.csr -out ./test/my_server/key/my_server.crt -config ./test/my_server/openssl.cnf -days 3650
因为使用了ca指令,所以配置文件中对default_ca进行配置。制作证书需要用到私钥,所以private_key字段配置的是正确的私钥的位置。
场景二:使用根CA,签发服务器证书
需要先生成根CA,再由根CA签终端证书。
生成根CA
创建目录:./test/my_root
创建文件:./test/my_root/index.txt ./test/my_root/serial ./test/my_root/openssl.cnf
创建文件夹:./test/my_root/key ./test/my_root/newcerts
在./test/my_root/serial文件中写入01
./test/my_root/openssl.cnf 内容如下:
ini
[ req ]
prompt?= no
x509_extensions = v3_ca ?# 配置成v3证书
string_mask = utf8only
req_extensions = v3_req ??# The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName?= example
organizationalUnitName = root CA
commonName = my root CA
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:TRUE
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ ca ]
default_ca = CA_default
[ CA_default ]
dir?= ./test/my_root ????#配置为对应目录
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl?= $dir/crl.pem
private_key = $dir/key/my_root.key ?#配置为对应私钥
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days = 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE,pathlen:0 ??#这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
openssl genpkey -algorithm rsa -out ./test/my_root/key/my_root.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ./test/my_root/key/my_root.key -out ./test/my_root/key/my_root.csr -config ./test/my_root/openssl.cnf
openssl ca -selfsign -in ./test/my_root/key/my_root.csr -out ./test/my_root/key/my_root.crt -config ./test/my_root/openssl.cnf -days 3650
生成服务器证书
创建目录:./test/my_server
创建文件:./test/my_server/index.txt ./test/my_server/serial ./test/my_server/openssl.cnf
创建文件夹:./test/my_server/key ./test/my_server/newcerts
在./test/my_server/serial文件中写入01
./test/my_server/openssl.cnf 内容如下:
ini
[ req ]
prompt ????????????= no
x509_extensions = v3_ca ?# 配置成v3证书
string_mask = utf8only
req_extensions = v3_req ??# The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
?
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName ???????= example
organizationalUnitName = it
commonName = my_server.cn
?
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName ?????= @alt_names
?
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
?
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:FALSE ??#这里配置为false,为终端证书。
?
[ ca ]
default_ca = CA_default
?
[ CA_default ]
dir ????= ./test/my_root
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
certificate = $dir/key/my_root.crt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl?= $dir/crl.pem
private_key = $dir/key/my_root.key
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:false
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
openssl genpkey -algorithm rsa -out ./test/my_server/key/my_server.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ./test/my_server/key/my_server.key -out ./test/my_server/key/my_server.csr -config ./test/my_server/openssl.cnf
openssl ca -in ./test/my_server/key/my_server.csr -out ./test/my_server/key/my_server.crt -config ./test/my_server/openssl.cnf -days 3650
备注:与场景一不同的是,该场景下,server证书由根ca颁发,所以在CA_default中配置my_root目录,且配置my_root证书和my_root私钥。
场景三:使用根证书,中间证书,中间证书签发服务器证书
生成根CA
这一步完全同场景2的步骤。
创建目录:./test/my_root
创建文件:./test/my_root/index.txt ./test/my_root/serial ./test/my_root/openssl.cnf
创建文件夹:./test/my_root/key ./test/my_root/newcerts
在./test/my_root/serial文件中写入01
./test/my_root/openssl.cnf 内容如下:
ini
[ req ]
prompt = no
x509_extensions = v3_ca # 配置成v3证书
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName = example
organizationalUnitName = root CA
commonName = my root CA
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:TRUE
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./test/my_root #配置为对应目录
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = $dir/key/my_root.key #配置为对应私钥
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE #这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
openssl genpkey -algorithm rsa -out ./test/my_root/key/my_root.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ./test/my_root/key/my_root.key -out ./test/my_root/key/my_root.csr -config ./test/my_root/openssl.cnf
openssl ca -selfsign -in ./test/my_root/key/my_root.csr -out ./test/my_root/key/my_root.crt -config ./test/my_root/openssl.cnf -days 3650
生成中间证书
创建目录:./test/secondary-ca
创建文件:./test/secondary-ca/index.txt ./test/secondary-ca/serial ./test/secondary-ca/openssl.cnf
创建文件夹:./test/secondary-ca/key ./test/secondary-ca/newcerts
在./test/secondary-ca/serial文件中写入01
./test/secondary-ca/openssl.cnf 内容如下:
ini
[ req ]
prompt = no
x509_extensions = v3_ca # 配置成v3证书
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName = example
organizationalUnitName = it
commonName = secondary ca
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:TRUE
[ v3_ca ]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./test/my_root
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
certificate = $dir/key/my_root.crt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = $dir/key/my_root.key
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 3650
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:TRUE,pathlen:0 #这里配置为true,为CA。
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
openssl req -new -newkey rsa:2048 -nodes -keyout ./test/secondary-ca/key/secondary-ca.key -out ./test/secondary-ca/key/secondary-ca.csr -config ./test/secondary-ca/openssl.cnf
openssl ca -in ./test/secondary-ca/key/secondary-ca.csr -out ./test/secondary-ca/key/secondary-ca.crt -config ./test/secondary-ca/openssl.cnf
备注:中间证书由根证书签名,所以CA_default配置的为my_root的证书和私钥。
Pathlen:0,表明该CA只能签发用户证书,不能再继续签发中间证书了。
生成服务器证书
创建目录:./test/my_server
创建文件:./test/my_server/index.txt ./test/my_server/serial ./test/my_server/openssl.cnf
创建文件夹:./test/my_server/key ./test/my_server/newcerts
在./test/my_server/serial文件中写入01
./test/my_server/openssl.cnf 内容如下:
ini
[ req ]
prompt = no
x509_extensions = v3_ca # 配置成v3证书
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request,配置SAN
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = shanghai
localityName = shanghai
organizationName = example
organizationalUnitName = it
commonName = my_server.cn
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.my_server.in
DNS.2 = www.test.com
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:FALSE #这里配置为false,为终端证书。
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./test/secondary-ca
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
certificate = $dir/key/secondary-ca.crt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = $dir/key/secondary-ca.key
RANDFILE = $dir/key/.rand
unique_subject = no
x509_extensions = usr_cert
copy_extensions = copy
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_ca
[ policy_ca ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ usr_cert ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA: FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
openssl genpkey -algorithm rsa -out ./test/my_server/key/my_server.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ./test/my_server/key/my_server.key -out ./test/my_server/key/my_server.csr -config ./test/my_server/openssl.cnf
openssl ca -in ./test/my_server/key/my_server.csr -out ./test/my_server/key/my_server.crt -config ./test/my_server/openssl.cnf -days 3650
备注:与场景一不同的是,该场景下,server证书由根ca颁发,所以在CA_default中配置my_root目录,且配置my_root证书和my_root私钥。
从上面可以看出,证书的序列号是由证书的颁发机构来维护的。那么看起来,根证书与二级证书是同一个序列表来维护的。如果要区分的话,可以修改配置文件。
确认生成的证书
下面是我生成的证书,从左至右分别是:服务器证书,中间证书,根证书 。
服务器证书
可以看见,服务器证书基本约束 中的Subject Type 是End Entity ,并且有一个项是服务器可选名称 ,还有一个授权密钥标识符。
中间证书
可以看见,中间证书基本约束 中的Subject Type 是CA ,还有一个授权密钥标识符 ,但没有服务器可选名称。
根证书
根证书基本约束 中的Subject Type 也是CA ,但没有授权密钥标识符。
部署服务器
构建证书链
由于是多级CA证书,所以,服务器需要把根CA、二级CA等证书都要发送给浏览器,给到web服务器的证书是要一个聚合的证书。
生成证书链:顺序是:用户证书 中间证书 根证书
cat my_server.crt cacert.crt secondary-ca.crt my_root.crt | tee my_all.crt
nginx服务器配置证书
ini
server {
listen 443 ssl;
server_name my_server.cn my_server.in;
ssl_certificate /**/my_all.crt;
ssl_certificate_key /**/my_server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
为了测试,配置hosts
192.168.133.134 my_server.cn
192.168.133.134 my_server.in
在浏览器上导入根CA,信任该自签CA。
然后通过my_server.cn访问。并查看证书。
openssl s_server搭建服务器
openssl s_server -key my_server.key -cert_chain my_all.crt -cert my_server.crt -debug -msg -verify_return_error -www
客户端同上,端口为4433,或者用s_client: openssl s_client -connect my_server.cn:4433 -CAfile my_root.crt -verify_return_error
或者用curl做客户端: curl https://my_server.cn:4433 --cacert my_root.crt
使用openssl命令开始服务器时发现,必须额外指定-cert_chain证书链,如果将证书链拼接后直接作为-cert,这种方式对s_server命令来说,并不生效。
用命令进行证书链的验证
首先验证二级证书,使用my_root来验: openssl verify -CAfile my_root.crt -show_chain secondary-ca.crt
其次,验服务器证书,需要带上上一级证书: openssl verify -CAfile <(cat my_root.crt secondary-ca.crt) -show_chain my_server.crt
验用户证书的第二种方式是:
openssl verify -CAfile my_root.crt -show_chain <(cat secondary-ca.crt my_server.crt)
二级在前,用户证书在后。这个顺序与证书链的顺序正好是反过来的。
配置两套证书:
openssl s_server -cert_chain a_root.crt -key aaa.pem -cert aaa.crt -debug -msg -dcert_chain b_root.crt -dkey bbb.pem -dcert bbb.crt
openssl s_client -connect *** -port 4433 -showcerts -verify_return_error -CAfile cacert.pem
openssl s_client -connect *** -port 4433 -showcerts -verify_return_error -CAfile cacert.pem -tls1_3 -sigalgs "RSA-PSS+SHA512"
双证书时怎么选择证书:
1是根据SNI选择不同的证书,即服务器给不同的域名配置不同的证书。
2是通过签名算法选配,服务器根据客户端支持的签名算法提供证书,顺序是ECC ED25519 ED448 RSA_PSS SHA
Tips
如果需要知道更具体的配置文件细节,以及命令的更多功能,需要去我的主页参考文章的前篇。