1.1 准备目录

mkdir ~/cert
cd ~/cert
mkdir root server client newcerts
echo 01 > serial
echo 01 > crlnumber
touch index.txt

1.2 修改openssl配置文件

vim openssl.cnf

备份

cp /etc/ssl/openssl.cnf /etc/openssl.cnf-bak

修改

vim /etc/ssl/openssl.conf

找到 [ req ],在区块最后面加上

req_extensions = v3_req

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = www.example.com #证书绑定的域名
DNS.2 = www.example.org
IP.1 = 192.168.1.1 #证书绑定的IP

找到 default_ca = CA_default 修改并添加以下内容

default_ca      = CA_Browser

[ CA_Browser ]

dir             = /root/cert/            # 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.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certs with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/root/ca.crt       # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/root/ca.pkey     # The private key

x509_extensions = usr_cert              # The extensions to add to the cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options

# Extension copying option: use with caution.
# copy_extensions = copy

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions        = crl_ext

default_days    = 3650                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = default               # use public key default MD
preserve        = no                    # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy          = policy_match

2. 创建CA根级目录

openssl genrsa -out root/ca.key 2048
openssl req -new -key root/ca.key -out root/ca.csr
========================================================================
#输出及输入
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN #国家
State or Province Name (full name) [Some-State]:GuangDong #省份
Locality Name (eg, city) []:ShenZhen # 城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YourCompanyName #公司名
Organizational Unit Name (eg, section) []: #可不填
Common Name (e.g. server FQDN or YOUR name) []: #可不填
Email Address []:[email protected] #
邮箱

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: #可不填
An optional company name []: #可不填
=============================================================================
openssl x509 -req -days 3650 -in root/ca.csr -signkey root/ca.key -out root/ca.crt

3. 创建服务器证书

openssl genrsa -out server/server.key 2048
openssl req -new -key server/server.key -out server/server.csr
========================================================================
#输出及输入
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN #国家
State or Province Name (full name) [Some-State]:GuangDong #省份
Locality Name (eg, city) []:ShenZhen # 城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YourCompanyName #公司名
Organizational Unit Name (eg, section) []: #可不填
Common Name (e.g. server FQDN or YOUR name) []:name #必填
Email Address []:[email protected] #
邮箱

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: #可不填
An optional company name []: #可不填
=============================================================================
openssl ca -in server/server.csr -cert root/ca.crt -keyfile root/ca.key -out server/server.crt -extensions v3_req -days 3650

4. 创建client证书

openssl genrsa -des3 -out client/client.key 2048
#输入及确认密码1
openssl req -new -key client/client.key -out client/client.csr
#输入密码1
=============================================================================
#输出及输入
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN #国家
State or Province Name (full name) [Some-State]:GuangDong #省份
Locality Name (eg, city) []:ShenZhen # 城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YourCompanyName #公司名
Organizational Unit Name (eg, section) []: #可不填
Common Name (e.g. server FQDN or YOUR name) []:#你的名字或组织 可不填
Email Address []:[email protected] #
邮箱

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: #可不填
An optional company name []: #可不填
=============================================================================
openssl ca -in client/client.csr -cert root/ca.crt -keyfile root/ca.key -out client/client.crt -days 3650

#非必要
#生成客户端集成证书pkcs12格式的文件
openssl pkcs12 -export -clcerts -in client/client.crt -inkey client/client.key -out client/client.pfx

5. Apache 配置


SSLEngine on
SSLCertificateFile "/root/cert/server/server.crt"
SSLCertificateKeyFile "/root/cert/server/server.key"
SSLVerifyClient require #必须验证证书
SSLCACertificateFile "/root/cert/root/ca.crt"
SSLVerifyDepth 10
SSLProtocol TLSv1.2 #SSL版本

6. 前端配置

#需引入 'fs' 和 'https'
axios({
    url: 'https://yourDomain.com/api/...',
    method: 'GET',
    httpsAgent: new https.Agent({
        passphrase: '123456',
        pfx: fs.readFileSync(resolve('./static/certificates/client.pfx')),
    })

}).then(....)