基于OpenSSL签署根CA证书、二级CA证书和SSL证书

发布时间: 更新时间: 总字数:3548 阅读时间:8m 作者: 分享 复制网址
专栏文章
  1. SSL/TLS原理详解
  2. 免费HTTPS证书Let's Encrypt安装教程
  3. 多域名(SAN/UCC)生成CSR操作指南
  4. 免费通配符/泛域名SSL证书申请
  5. 如何信任自签 CA 证书
  6. 基于OpenSSL签署根CA证书、二级CA证书和SSL证书(当前)
  7. 基于OpenSSL签署根CA证书、二级CA证书(x-ca)
  8. Let’s Encrypt 私有部署方案

本文介绍基于OpenSSL自建CA证书、二级CA证书和SSL证书,以及如何使用 openssl 查看证书。

基础知识

术语

  • CA证书颂发机构(Certificate Authority) 是指一个中心化的,可信任的证书颁发机构
  • 数字证书(Digital Certificate) 使用CA私钥加密(拥有者信息、公钥信息和拥有者公钥)得到的数据,即是数字证书
  • PKI公钥基础设施(Public Key Infrastructure) 用来实现基于公钥密码体制的密钥和证书的产生、管理、存储、分发和撤销等功能

OpenSSL工具介绍

openssl是一个开源程序的套件、这个套件有三个部分组成:

  1. libcryto 是一个具有通用功能的加密库,里面实现了众多的加密库
  2. libssl 是实现ssl机制的,它是用于实现TLS/SSL的功能
  3. openssl 是个多功能命令行工具,它可以实现加密解密,甚至还可以当CA来用,可以让你创建证书、吊销证书

证书格式介绍

  • .key:私钥文件,如ca.key
  • .crt:数字证书(Digital Certificate)文件,如ca.crt
  • .bundle.crt:最终在NGINX上配置的数字证书文件,通常包含两部分,如:<domain>.crtca.crt
  • .chain.crt:证书链文件
  • .srlopenssl ca签名过程中产生的Serial Number存放的文件
  • .csr:证书签名请求(Certificate Signing Request)文件,如all.xiexianbin.cn.csr
  • .crl:证书吊销列表(Certificate Revocation List)
  • .pem:包含私钥的证书

非对称加密算法

非对称加密算法需要两个密钥:

  • 公开密钥(publickey)简称公钥
  • 私有密钥(privatekey)简称私钥
  • 公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;私钥仅有一把,但公钥可以是多个
  • 私钥加密的内容,所有公钥都能解开
  • 公钥加密的内容,只有私钥才能解开

X.509

X.509是国际电信联盟针对PKI制定的标准RFCs

一个X.509 v3版本的数字证书包含的结构如下:

  • Version - 必须是v3
  • Serial Number - 每个证书都有唯一的序列号
  • Algorithm ID - 算法ID,与底下的证书签名算法必须一致
  • Issuer - 发行者
  • Validity - 指明有效期
  • Subject - 拥有者的相关信息,如 C=CN, ST=Henan, L=Zhengzhou, ... CN=*.xiexianbin.cn
  • Subject public key info
  • Issuer Unique Identifier (optional)
  • Subject Unique Identifier (optional)
  • Extensions (optional) - 拓展,尤其是Subject Alternative Name的拓展非常关键
    • Subject Key Identifier (optional)
    • Authority Key Identifier (optional)
    • Subject Alternative Name: 重要
      • 通配证书(Wildcard Certificates)指的是像*.xiexianbin.cn一类的证书
    • Basic Constraints (optional)
  • 证书签名算法(Certificate Signature Algorithm)如:SHA-256
  • 证书签名(Certificate Signature)

创建CA

签发一级CA证书

方法一:直接通过命令行签名

生成根密钥

openssl genrsa -out cakey.key 4096

为了安全起见,修改cakey.key私钥文件权限为600400,也可以使用子shell生成( umask 077; openssl genrsa -out cakey.key 4096 ),下面不再重复。

示例:

# openssl genrsa -out cakey.key 4096
Generating RSA private key, 4096 bit long modulus
.......................++
.........................................................................................................................................................................................................................................................................................................................++
e is 65537 (0x10001)

生成根证书

使用req命令生成自签证书:

openssl req -new -x509 -days 14610 -key cakey.key -out cacert.crt
  • 示例
# openssl req -new -x509 -days 14610 -key cakey.key -out cacert.crt
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Zhengzhou
Organization Name (eg, company) [Default Company Ltd]:X Technology Co. Ltd.
Organizational Unit Name (eg, section) []:X Root CA Trust
Common Name (eg, your name or your server's hostname) []:X Root CA - R3
Email Address []:me@xiexianbin.cn

查看证书

openssl x509 -in cacert.crt -noout -text

生成SSL密钥

以上都是在CA服务器上做的操作,而且只需进行一次,现在转到nginx服务器上执行:

cd /etc/nginx/ssl
openssl genrsa -out all.xiexianbin.cn.key 2048

这里测试的时候CA中心与要申请证书的服务器是同一个。

生成证书签署请求

# openssl req -new -days 3650 -key all.xiexianbin.cn.key -out all.xiexianbin.cn.csr
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ShangHai
Locality Name (eg, city) [Default City]:ShangHai
Organization Name (eg, company) [Default Company Ltd]:xiexianbin.cn
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:*.xiexianbin.cn
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

同样会提示输入一些内容,其它随便,除了Commone Name一定要是你要授予证书的服务器域名或主机名,challenge password不填。

私有CA签署证书

接下来要把上一步生成的证书请求csr文件,发到CA服务器上,在CA上执行:

openssl ca -in all.xiexianbin.cn.csr -out all.xiexianbin.cn.crt
# 上面的命令生成的证书不能识别,试试下面的命令
openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA /etc/pki/CA/cacert.crt -CAkey /etc/pki/CA/private/cakey.key -CAcreateserial -out all.xiexianbin.cn.crt

示例:

创建ext:all.xiexianbin.cn.ext

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=@alt_names
extendedKeyUsage=serverAuth
# crlDistributionPoints=URI:https://ca.xiexianbin.cn/crl.crl

[alt_names]
DNS.1 = xiexianbin.cn
DNS.2 = *.xiexianbin.cn
DNS.3 = kb.cx
DNS.4 = *.kb.cx
DNS.4 = localhost
# openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA cacert.crt -CAkey cakey.key -CAcreateserial -out all.xiexianbin.cn.crt -extfile all.xiexianbin.cn.ext -sha256
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=xiexianbin.cn/OU=IT/CN=*.xiexianbin.cn/emailAddress=me@xiexianbin.cn
Getting CA Private Key

说明:

  • -days 必须少于 825 天,否则报错 NET::ERR_CERT_REVOKED

上面签发过程其实默认使用了-cert cacert.crt -keyfile cakey.key,这两个文件就是前两步生成的位于/etc/pki/CA下的根密钥和根证书。将生成的crt证书发回nginx服务器使用。

到此我们已经拥有了建立ssl安全连接所需要的所有文件,并且服务器的crtkey都位于配置的目录下。

验证生成的SSL证书

校验证书是否被 CA 证书签名:

# openssl verify -CAfile cacert.crt all.xiexianbin.cn.crt
all.xiexianbin.cn.crt: OK

生成bundle.crt

cat all.xiexianbin.cn.crt cacert.crt > all.xiexianbin.cn.bundle.crt

方法二:通过配置文件签名

上述方法是通过命令行,过程过于繁琐,可以使用配置文件进行签名

pki目录结构

CentOS上有关ssl证书的目录结构:

/etc/pki/CA/
            newcerts    存放CA签署(颁发)过的数字证书(证书备份目录)
            private     用于存放CA的私钥
            crl         吊销的证书
/etc/pki/tls/
             cert.pem    软链接到certs/ca-bundle.crt
             certs/      该服务器上的证书存放目录,可以房子自己的证书和内置证书
                   ca-bundle.crt    内置信任的证书
             private    证书密钥存放目录
             openssl.cnf    openssl的CA主配置文件

修改CA的一些配置文件

CA要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好CA的配置文件、序列号、索引等等。

vi /etc/pki/tls/openssl.cnf:

...
[ 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.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/private/cakey.key # The private key
RANDFILE        = $dir/private/.rand    # private random number file
...
default_days    = 3650                  # how long to certify for
...
# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
...
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = CN
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Henan
...
[ req_distinguished_name ] 部分主要是颁证时一些默认的值,可以不动

一定要注意[ policy_match ]中的设定的匹配规则,是有可能因为证书使用的工具不一样,导致即使设置了csr中看起来有相同的countryName,stateOrProvinceName等,但在最终生成证书时依然报错:

Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (GuangDong) and the request (GuangDong)
touch index.txt serial

在CA目录下创建两个初始文件:

# touch index.txt serial
# echo 01 > serial

签名:

openssl ca -config /etc/pki/tls/openssl.cnf -out all.xiexianbin.cn.crt -in all.xiexianbin.cn.csr -extfile all.xiexianbin.cn.cnf -batch

签发中级CA证书

生成二级CA密钥

# openssl genrsa -out secondcakey.key 4096
Generating RSA private key, 4096 bit long modulus
......................++
.......................................................................................................................................................................++
e is 65537 (0x10001)

生成二级CA证书签名请求(CSR)

使用req命令生成自签证书:

# openssl req -new -key secondcakey.key -out secondcsr.csr
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Zhengzhou
Organization Name (eg, company) [Default Company Ltd]:X Technology Co. Ltd.  ## 务必确保Organization Name与根CA证书相同
Organizational Unit Name (eg, section) []:X Authority
Common Name (eg, your name or your server's hostname) []:X Authority - R3
Email Address []:me@xiexianbin.cn

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

生成二级CA证书

创建ext:secondcert.ext

basicConstraints=CA:true
crlDistributionPoints=URI:https://ca.xiexianbin.cn/crl.pem
# openssl x509 -req -days 7305 -CA cacert.crt -CAkey cakey.key -CAcreateserial -in secondcsr.csr -out secondcacert.crt -extfile secondcert.ext -sha256
Signature ok
subject=/C=CN/ST=Henan/L=Zhengzhou/O=X Technology Co. Ltd./OU=X Root CA Trust/CN=X Authority - R3/emailAddress=me@xiexianbin.cn
Getting CA Private Key

同样会提示输入一些内容,其它随便,除了Commone Name一定要是你要授予证书的服务器域名或主机名,challenge password不填。

验证二级CA证书

# openssl verify -CAfile cacert.crt secondcacert.crt
secondcacert.crt: OK

生成证书链文件

cat secondcacert.crt cacert.crt > secondcacert.chain.crt

使用二级CA证书签名

# openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA secondcacert.crt -CAkey secondcakey.key -CAcreateserial -out all.xiexianbin.cn.crt -extfile all.xiexianbin.cn.ext -sha256
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=xiexianbin.cn/OU=IT/CN=*.xiexianbin.cn/emailAddress=me@xiexianbin.cn
Getting CA Private Key

验证生成的SSL证书

校验证书是否被 CA 证书签名:

# openssl verify -CAfile secondcacert.chain.crt all.xiexianbin.cn.crt
all.xiexianbin.cn.crt: OK

生成bundle.crt

cat all.xiexianbin.cn.crt secondcacert.crt > all.xiexianbin.cn.bundle.crt

使用SSL证书

nginx配置

在nginx配置文件(可能是/etc/nginx/nginx.conf)的server指令下添加:

    ssl_certificate            /etc/nginx/conf.d/cert/all.xiexianbin.cn.bundle.crt;
    ssl_certificate_key        /etc/nginx/conf.d/cert/all.xiexianbin.cn.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl on;

同时注意 server_name 与证书申请时的 Common Name 要相同,打开443端口。当然关于web服务器加密还有其他配置内容,如只对部分URL加密,对URL重定向实现强制https访问,请参考其他资料。

访问域名问题

浏览器作为客户端去访问https加密的服务器,一般不用去手动做其他设置,如https://www.xiexianbin.cn,这是因为Chrome、FireFox、Safari、IE等浏览器已经内置了大部分常用的CA的根证书,但自建CA的根证书就不再浏览器的信任列表中,访问时会提示红色错误。

如果你要自己做CA,别忘了客户端需要导入CA的证书(CA的证书是自签名的,导入它意味着你“信任”这个CA签署的证书)。而商业CA的一般不用,因为它们已经内置在你的浏览器中了。

导出导入自签名证书

如何信任自签 CA 证书

其他工具

  • cfsslCloudFlare 公司开发的一款开源的工具包,被用来捆绑TLS/SSL证书链,并作为内部证书颁发机构基础架构
  • go-ca SSL自签名客户端,自动生成Root CA、二级CA、域名证书。基于 x-ca 格式开发。
专栏文章
  1. SSL/TLS原理详解
  2. 免费HTTPS证书Let's Encrypt安装教程
  3. 多域名(SAN/UCC)生成CSR操作指南
  4. 免费通配符/泛域名SSL证书申请
  5. 如何信任自签 CA 证书
  6. 基于OpenSSL签署根CA证书、二级CA证书和SSL证书(当前)
  7. 基于OpenSSL签署根CA证书、二级CA证书(x-ca)
  8. Let’s Encrypt 私有部署方案
最新评论
加载中...
Home Archives Categories Tags Statistics