利用openssl命令搭建私有CA管理证书

2018-01-05|Categories: External cmd, Linux, Magedu-training|

搭建私有CA

搭建私有CA主要是为了测试,真正对外提供服务的主机必须向权威的CA——例如Let’s Encrypt——申请证书,而不能使用私有CA签发的证书。

任何一台安装了openssl软件包的主机都可以成为私有CA,只要生成一个私钥,然后生成一张自签名证书即可,但所有相关文件必须存放在指定路径,这些路径由/etc/pki/tls/openssl.cnf文件的CA_default片段指定:

[ CA_default ]

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

certificate     = $dir/cacert.pem       # 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/private/cakey.pem# The private key

生成CA的私钥

cd /etc/pki/CA

# 私钥文件使用尽可能小的权限,`umask 066`让生成文件默认权限为600
# 为了不影响当前shell的umask设置,用圆括号包围命令,使其在子shell执行
#
(umask 066; openssl genrsa -out private/cakey.pem 2048)

生成CA的自签名证书

# `-x509`专用于CA生成自签名证书
# CA的数字证书的有效期不能太短,`-days 7300`设置有效期为20年
#
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 7300

生成自签名证书的过程中,需要提交必要的信息,例如国家名、州或省、组织名、通用名,其它信息是可选的:

如上图,自签名证书生成之后,可以看到签发者(issuer)、被签发者(subject)是相同的,查看命令是:

openssl x509 -in cacert.pem -noout -issuer -subject

通过简单的两步,就完成了私有CA的搭建。

向CA申请证书

假设在另一台主机上运行着web服务器,现在需要申请一张证书,以便整个站点从http升级到https,步骤如下:

生成私钥

# 非CA的证书不要放到`/etc/pki/CA`
#
cd /etc/pki/tls

(umask 066; openssl genrsa -out private/test.pem 2048)

生成证书签名请求(CSR)

openssl req -new -key private/test.pem -out certs/test.csr

生成过程中同样需要提交必要信息,默认情况下,国家名、州或省、组织名必须和CA证书相同,这里为了演示各种问题的解决方法,特意设置了不同的信息,例如:省名改成Guangdong,组织名改成LIYANG85.COM:

这个请求文件主要包含了申请者的subject、公钥。

将CSR传送给CA

scp certs/test.csr root@192.168.19.71:/etc/pki/CA/certs/

CA签署证书

CA收到客户的CSR之后,就可以着手签署了,但如果是第一次签署,还必须准备好相关的文件,否则会报错导致签署失败。

准备证书索引数据库文件

touch /etc/pki/CA/index.txt

准备证书序列号文件

# `01`是16进制数,表示即将颁发的证书的序列号,不是必须从01开始
#
echo 01 > /etc/pki/CA/serial

修改证书签署策略

解决了缺少文件的报错之后,openssl开始签署流程,第一步就发现CSR包含的省名信息与CA的不匹配,报错后退出:

这是因为在/etc/pki/tls/openssl.cnf中,签署策略默认被设置为policy_match,这个策略要求CSR包含的国家名、州或省、组织名必须和CA证书相同(match),只要把策略改为policy_anything,就可以不同:

正式签署

修改签署策略之后,签署命令

openssl ca -in /etc/pki/CA/certs/test.csr -out certs/test.crt -days 365

终于执行成功:

签署的实质就是用CA(颁发者)的私钥加密申请者(被颁发者)的公钥。查看刚签署的证书的颁发者和被颁发者:

openssl x509 -in certs/test.crt -noout -issuer -subject

在签署过程中,除了生成的证书,还有以下文件都被修改:

  • index.txt
    $ cat index.txt
    
    # V = Valid
    #
    V   190104035045Z       01  unknown /C=CN/ST=Guangdong/L=Shenzhen/O=LIYANG85.COM/CN=*.liyang85.com/emailAddress=admin@liyang85.com
    
  • index.txt.attr
    $ cat index.txt.attr
    
    # 规定一个subject只能签发一个独一无二的证书
    # 如果设为`no`,对同一个subject可以签发多个证书
    #
    unique_subject = yes
    
  • serial
    $ cat serial
    
    # 下一次签发证书的序列号
    #
    02
    
  • newcerts/01.pem
    $ md5sum certs/test.crt newcerts/01.pem
    
    # 在certs目录生成指定证书的同时,默认会在newcerts目录生成同样内容的证书,
    # 这个证书用于备份和撤销,以生成时的序列号作为文件名
    #
    1da7c867ffda7bc29120df80ff9cd99c  certs/test.crt
    1da7c867ffda7bc29120df80ff9cd99c  newcerts/01.pem
    

CA撤销证书

客户端首先确定需要撤销的证书的序列号(serial)、被颁发者(subject):

openssl x509 -in want_to_revoke.pem -noout -serial -subject

然后把输出信息发送给CA,CA拿客户提交的信息与/etc/pki/CA/newcerts/目录内证书比对,这个目录的证书是以序列号作为文件名的,确认序列号相同、被颁发者相同之后,就可以撤销了:

cd /etc/pki/CA
openssl ca -revoke newcerts/serial_from_client.pem

证书撤销之后,index.txt文件的内容也会被修改:

$ cat index.txt

# R = Revoked
#
R   190104035045Z   180104091520Z   01  unknown /C=CN/ST=Guangdong/L=Shenzhen/O=LIYANG85.COM/CN=*.liyang85.com/emailAddress=admin@liyang85.com

生成证书撤销列表(CRL)

# 第一次生成CRL时必须生成crlnumber文件
#
echo 01 > crlnumber

# `crl.pem`必须位于`/etc/pki/CA`
#
openssl ca -gencrl -out crl.pem

其它openssl用法

查看证书

openssl x509 -in cert_name.pem -noout -text

查看证书签名请求

openssl req -in csr_name.csr -noout -text

# 验证CSR
#
openssl req -in csr_name.csr -noout -text -verify

查看证书撤销列表

openssl crl -in crl.pem -noout -text

查看私钥

openssl rsa -in key_name.pem -noout -text

# 验证私钥
#
openssl rsa -in key_name.pem -noout -check

从私钥生成公钥

openssl rsa -in test.pem -pubout -out test.pem.pub

Leave A Comment