私有  CA  搭建与管理:使用  OpenSSL  创建企业内部证书体系

在企业内部网络中,使用私有证书颁发机构(CA)可以摆脱对公共  CA  的依赖,实现低成本、高可控的内部  TLS  加密、代码签名、设备认证等。本文将详细介绍如何使用开源工具  OpenSSL  搭建一套完整的私有  CA  体系,包括根  CA、中间  CA、服务器证书和客户端证书的签发,以及SSL证书吊销列表(CRL)的管理。

1.  为什么需要私有  CA?

成本控制:公共  CA  签发的证书通常按年收费,内部大量设备需要证书时成本高昂。

灵活性:可自定义证书有效期、扩展字段(如  SAN)、密钥用法等。

安全性:私钥完全掌握在自己手中,无需将内部域名暴露给第三方。

自动化:便于与内部运维系统集成,实现自动化签发和续签。

OpenSSL  是开源的加密库,提供了完整的命令行工具,足以完成  CA  的搭建和证书管理。

2.  准备工作

2.1  安装  OpenSSL

大多数  Linux  发行版默认已安装  OpenSSL。检查版本:

bash

openssl  version

若未安装,使用包管理器安装(以  Ubuntu  为例):

bash

sudo  apt  update  &&  sudo  apt  install  openssl

2.2  规划目录结构

建议为  CA  创建独立的目录树,便于管理和备份。示例结构:

~/ca/

├──  root-ca/                              #  根CA目录

│      ├──  certs/                          #  已签发的证书(根CA签发的中间CA证书)

│      ├──  crl/                              #  吊销列表

│      ├──  newcerts/                    #  新签发的证书副本

│      ├──  private/                      #  私钥(权限必须为600)

│      ├──  index.txt                    #  证书数据库

│      ├──  serial                          #  下一个证书序列号

│      └──  openssl.cnf                #  根CA专用配置文件

├──  intermediate-ca/              #  中间CA目录(可选)

│      ├──  certs/

│      ├──  crl/

│      ├──  newcerts/

│      ├──  private/

│      ├──  index.txt

│      ├──  serial

│      └──  openssl.cnf

└──  certs/                                  #  最终颁发的各类证书(按用途存放)

        ├──  server/

        ├──  client/

        └──  ...

创建目录:

bash

mkdir  -p  ~/ca/{root-ca,intermediate-ca,certs/{server,client}}

cd  ~/ca

3.  搭建根  CA(Root  CA)

根  CA  是整个信任链的顶点,私钥必须严格保护。通常根  CA  仅用于签发中间  CA,不直接签发最终用户SSL证书,以减少私钥暴露风险。

3.1  准备根  CA  配置文件

创建  `root-ca/openssl.cnf`,内容如下(可根据需要调整):

ini

[  ca  ]

default_ca  =  CA_default

[  CA_default  ]

#  目录结构

dir                              =  /home/username/ca/root-ca

certs                          =  $dir/certs

crl_dir                      =  $dir/crl

new_certs_dir          =  $dir/newcerts

database                    =  $dir/index.txt

serial                        =  $dir/serial

RANDFILE                    =  $dir/private/.rand

#  私钥和证书

private_key              =  $dir/private/ca.key.pem

certificate              =  $dir/certs/ca.cert.pem

#  默认有效期

default_days            =  3650

default_crl_days    =  30

default_md                =  sha256

preserve                    =  no

#  策略(根CA签发中间CA时使用)

policy                        =  policy_loose

[  policy_loose  ]

countryName                          =  optional

stateOrProvinceName          =  optional

localityName                        =  optional

organizationName                =  optional

organizationalUnitName    =  optional

commonName                            =  supplied

emailAddress                        =  optional

[  req  ]

#  用于生成CSR的选项

default_bits                =  4096

distinguished_name    =  req_distinguished_name

string_mask                  =  utf8only

default_md                    =  sha256

[  req_distinguished_name  ]

countryName                                          =  Country  Name  (2  letter  code)

countryName_default                          =  CN

stateOrProvinceName                          =  State  or  Province  Name

stateOrProvinceName_default          =  Beijing

localityName                                        =  Locality  Name

localityName_default                        =  Beijing

organizationName                                =  Organization  Name

organizationName_default                =  Example  Inc

organizationalUnitName                    =  Organizational  Unit  Name

organizationalUnitName_default    =  IT

commonName                                            =  Common  Name

commonName_default                            =  Example  Root  CA

commonName_max                                    =  64

[  v3_ca  ]

#  根CA扩展

subjectKeyIdentifier      =  hash

authorityKeyIdentifier  =  keyid:always,issuer

basicConstraints              =  critical,  CA:TRUE,  pathlen:1

keyUsage                              =  critical,  digitalSignature,  keyCertSign,  cRLSign

>  注意:`dir`  路径需替换为实际路径。建议使用绝对路径。

3.2  初始化数据库和序列号

bash

cd  ~/ca/root-ca

touch  index.txt

echo  01  >  serial

3.3  生成根  CA  私钥和自签名证书

bash

#  生成私钥(2048位或4096位,推荐4096)

openssl  genrsa  -out  private/ca.key.pem  4096

chmod  400  private/ca.key.pem      #  严格限制权限

#  生成自签名证书(有效期10年)

openssl  req  -config  openssl.cnf  -key  private/ca.key.pem  \

        -new  -x509  -days  3650  -sha256  -extensions  v3_ca  \

        -out  certs/ca.cert.pem

命令执行后会提示输入证书主题信息,按  `openssl.cnf`  中的默认值或手动填写。

3.4  验证根  CA  证书

bash

openssl  x509  -in  certs/ca.cert.pem  -text  -noout

确认  `Basic  Constraints`  包含  `CA:TRUE`  且  `Key  Usage`  正确。

4.  搭建中间  CA(Intermediate  CA)

使用中间  CA  签发最终用户证书,即使中间  CA  私钥泄露,也可通过根  CA  吊销其证书,无需重建整个信任链。

4.1  准备中间  CA  配置文件

复制根  CA  的  `openssl.cnf`  到  `intermediate-ca/`,并修改以下部分:

ini

[  CA_default  ]

dir                              =  /home/username/ca/intermediate-ca

private_key              =  $dir/private/intermediate.key.pem

certificate              =  $dir/certs/intermediate.cert.pem

default_days            =  730              #  中间CA签发的证书默认2年

default_crl_days    =  30

policy                        =  policy_loose

[  v3_intermediate_ca  ]

subjectKeyIdentifier      =  hash

authorityKeyIdentifier  =  keyid:always,issuer

basicConstraints              =  critical,  CA:TRUE,  pathlen:0

keyUsage                              =  critical,  digitalSignature,  keyCertSign,  cRLSign

>  注意:中间  CA  的  `pathlen`  设为  0,表示不能再签发下级  CA。

4.2  初始化中间  CA  目录

bash

cd  ~/ca/intermediate-ca

touch  index.txt

echo  01  >  serial

4.3  生成中间  CA  私钥和  CSR

bash

#  生成私钥

openssl  genrsa  -out  private/intermediate.key.pem  4096

chmod  400  private/intermediate.key.pem

#  生成  CSR(证书签名请求)

openssl  req  -config  openssl.cnf  -new  -sha256  \

        -key  private/intermediate.key.pem  \

        -out  intermediate.csr

填写主题信息时,`Common  Name`  应为例如  `Example  Intermediate  CA`。

4.4  使用根  CA  签发中间  CA  证书

bash

cd  ~/ca/root-ca

openssl  ca  -config  openssl.cnf  -extensions  v3_intermediate_ca  \

        -days  3650  -notext  -md  sha256  \

        -in  ../intermediate-ca/intermediate.csr  \

        -out  ../intermediate-ca/certs/intermediate.cert.pem

输入根  CA  私钥密码(如果设置了)。签发后,可查看证书:

bash

openssl  x509  -in  ../intermediate-ca/certs/intermediate.cert.pem  -text  -noout

4.5  创建证书链文件

将根  CA  和中间  CA  的证书合并为一个文件,供服务端配置使用:

bash

cat  ../intermediate-ca/certs/intermediate.cert.pem  \

        ../root-ca/certs/ca.cert.pem  >  ../intermediate-ca/certs/ca-chain.cert.pem

5.  签发服务器证书

服务器证书用于保护  Web  服务、API  等,通常需要包含主题备用名称(SAN)。

5.1  准备服务器证书配置文件(可选)

为简化命令,可以为服务器证书创建扩展配置文件  `server.cnf`:

ini

[  req  ]

default_bits                =  2048

distinguished_name    =  req_distinguished_name

req_extensions            =  req_ext

prompt                            =  no

[  req_distinguished_name  ]

countryName                          =  CN

stateOrProvinceName          =  Beijing

localityName                        =  Beijing

organizationName                =  Example  Inc

organizationalUnitName    =  IT

commonName                            =  www.example.com

[  req_ext  ]

subjectAltName  =  @alt_names

[  alt_names  ]

DNS.1  =  www.example.com

DNS.2  =  example.com

DNS.3  =  internal.example.com

IP.1    =  10.0.0.1

5.2  生成服务器私钥和  CSR

bash

cd  ~/ca/certs/server

#  生成私钥

openssl  genrsa  -out  server.key.pem  2048

chmod  400  server.key.pem

#  生成  CSR(使用配置文件)

openssl  req  -new  -sha256  -key  server.key.pem  \

        -config  server.cnf  -out  server.csr

如果不使用配置文件,也可交互式输入,但  SAN  需要通过  `-addext`  添加(OpenSSL  1.1.1+)。

5.3  使用中间  CA  签发证书

bash

cd  ~/ca/intermediate-ca

openssl  ca  -config  openssl.cnf  -extensions  server_cert  \

        -days  730  -notext  -md  sha256  \

        -in  ../certs/server/server.csr  \

        -out  ../certs/server/server.cert.pem


其中  `server_cert`  扩展应在中间  CA  的  `openssl.cnf`  中定义:

ini

[  server_cert  ]

basicConstraints              =  CA:FALSE

keyUsage                              =  digitalSignature,  keyEncipherment

extendedKeyUsage              =  serverAuth

subjectAltName                  =  @alt_names

[  alt_names  ]

DNS.1  =  www.example.com

DNS.2  =  example.com

IP.1    =  10.0.0.1

>  注意:实际签发时,可以在命令行使用  `-extfile`  指定扩展文件,避免修改主配置文件。

例如:

bash

openssl  ca  -config  openssl.cnf  -extfile  server.cnf  -extensions  server_cert  ...

5.4  验证证书

bash

openssl  verify  -CAfile  ca-chain.cert.pem  ../certs/server/server.cert.pem

若返回  `OK`  则表示证书链验证通过。

6.  签发客户端证书

客户端证书用于双向  TLS  认证(mTLS),验证客户端身份。

6.1  准备客户端证书配置文件  `client.cnf`

ini

[  req  ]

default_bits                =  2048

distinguished_name    =  req_distinguished_name

req_extensions            =  req_ext

prompt                            =  no


[  req_distinguished_name  ]

countryName                          =  CN

stateOrProvinceName          =  Beijing

localityName                        =  Beijing

organizationName                =  Example  Inc

organizationalUnitName    =  IT

commonName                            =  John  Doe

[  req_ext  ]

subjectAltName  =  email:john@example.com

6.2  生成客户端私钥和  CSR

bash

cd  ~/ca/certs/client

openssl  genrsa  -out  client.key.pem  2048

openssl  req  -new  -sha256  -key  client.key.pem  \

        -config  client.cnf  -out  client.csr

6.3  签发客户端证书

中间  CA  的配置文件中需定义  `client_cert`  扩展:

ini

[  client_cert  ]

basicConstraints              =  CA:FALSE

keyUsage                              =  digitalSignature

extendedKeyUsage              =  clientAuth

subjectAltName                  =  email:copy

签发命令:

bash

cd  ~/ca/intermediate-ca

openssl  ca  -config  openssl.cnf  -extensions  client_cert  \

        -days  365  -notext  -md  sha256  \

        -in  ../certs/client/client.csr  \

        -out  ../certs/client/client.cert.pem

6.4  转换为  PKCS#12  格式(用于浏览器)

bash

openssl  pkcs12  -export  -clcerts  -in  client.cert.pem  \

        -inkey  client.key.pem  -out  client.p12  -password  pass:changeit

7.  证书吊销列表(CRL)管理

当私钥泄露或员工离职时,需及时吊销证书。

7.1  吊销证书

bash

cd  ~/ca/intermediate-ca

openssl  ca  -config  openssl.cnf  -revoke  ../certs/server/server.cert.pem

吊销原因可通过  `-crl_reason`  指定,如  `keyCompromise`、`affiliationChanged`  等。

7.2  生成  CRL

bash

openssl  ca  -config  openssl.cnf  -gencrl  -out  crl/intermediate.crl.pem

查看  CRL:

bash

openssl  crl  -in  crl/intermediate.crl.pem  -text  -noout

7.3  定期更新  CRL

可设置  cron  任务定期重新生成  CRL,并分发到需要检查吊销状态的系统。

8.  证书续签与轮换

证书到期前需续签。最简单的方法是重新生成  CSR(或重用原私钥),然后签发新证书。

对于服务器SSL证书,可提前生成新证书并替换,确保服务不中断。

9.  安全最佳实践

私钥保护:

    根  CA  私钥应离线保存(如加密  USB  或  HSM),仅在签发中间  CA  时短暂使用。

    中间  CA  私钥可在线但应严格限制权限(600),并设置强密码。

      密钥长度:至少  2048  位  RSA,推荐  4096  位;ECC(如  prime256v1)也可考虑。

      有效期:根  CA  建议  10  年,中间  CA  5  年,服务器/客户端证书  1-2  年。

      命名规范:证书  CN  和  SAN  应清晰明确,避免模糊。

      备份:定期备份  CA  目录,尤其是  `index.txt`、`serial`、私钥(加密)。

      监控:记录所有证书签发和吊销操作,及时发现异常。

      使用  HSM:高安全场景使用硬件安全模块存储私钥。

10.  常用命令速查

操作        命令

  生成  RSA  私钥      `openssl  genrsa  -out  key.pem  2048`  

  查看证书      `openssl  x509  -in  cert.pem  -text  -noout`  

  验证证书链      `openssl  verify  -CAfile  chain.pem  cert.pem`  

  生成  CSR(交互)    `openssl  req  -new  -key  key.pem  -out  cert.csr`  

  生成  CSR(非交互)    `openssl  req  -new  -key  key.pem  -config  req.cnf  -out  cert.csr`  

  签发证书(CA)    `openssl  ca  -config  openssl.cnf  -in  cert.csr  -out  cert.pem`  

  吊销证书      `openssl  ca  -config  openssl.cnf  -revoke  cert.pem`  

  生成  CRL      `openssl  ca  -config  openssl.cnf  -gencrl  -out  crl.pem`  

  转换  PKCS#12    `openssl  pkcs12  -export  -in  cert.pem  -inkey  key.pem  -out  bundle.p12`  

结语

通过  OpenSSL  搭建私有  CA  体系,企业可以完全自主管理内部证书生命周期。本文所述步骤已在实际生产环境中验证,读者可根据自身需求调整有效期、密钥强度等参数。建议配合自动化工具(如  cfssl、Easy-RSA  或  Ansible)实现更高效的证书管理,并定期审视安全策略。

如果遇到问题,可查阅  OpenSSL  官方文档或使用  `openssl`  命令的  `-help`  选项获取详细用法