CA和PKI介绍
CA(Certificate Authority),翻译过来就叫作证书颁发机构。用于实现数字证书的管理,包括证书颁发、吊销、续期等。
PKI(Registration Authority ),翻译过来叫作注册机构,负责接收请求并验证实体的身份,然后指示 CA 为其颁发或撤销证书。
CA和PKI的关系:PKI 是一个更大的框架或系统,而 CA 是 PKI 中的一个核心组件
搭建私有CA
使用OpenSSL可以自己搭建一个私有的CA,实现私有证书的管理。
1、安装OpenSSL
一般Linux发行版系统默认就安装了OpenSSL的,如果没有可以通过包管理工具或者源码编译安装。
OpenSSL中文网: https://www.openssl.net.cn/
2、创建目录结构
使用OpenSSL搭建私有CA时,清晰目录结构有助于组织和管理CA操作,所以我们要创建以下目录:
(1)创建工作目录,将CA的所有文件放在一个专门的目录中
mkdir /etc/pki/CA
(2)创建相关子目录,不同的子目录存放不同的文件
mkdir /etc/pki/CA/{certs,crl,newcerts,private}
# 注意这个文件初始时一定要为空,不然后期没法颁发证书
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
目录说明:
-
certs目录:用于统一存放CA签发的证书
-
crl目录:用于存放一个证书吊销文件,这个文件的内容记录了吊销证书的信息
-
newcerts目录:这个目录存放的是刚创建的证书
-
private:存放的是CA的私钥文件
文件说明:
-
index.txt文件: 是OpenSSL用来跟踪哪些证书已经被签署的数据库。对于一个新的CA,index.txt应该是一个空文件,如果这个文件非空,签发证书的时候会失败。
-
serial文件:存放颁发证书的编号的文件,每当签发新证书时,OpenSSL会读取这个文件中的值作为其序列号,并增加该值以供下次使用,所以需要给他赋初值。
3、编辑配置文件
只有在与证书、证书请求、和与PKI相关的操作有关时才会读取openssl的配置文件,其它例如加密解密、非对称加密解密、哈希算法这些操作是不会读取配置文件内容。
所以编辑openssl的配置文件目的在于定义和定制OpenSSL命令行工具的行为,在配置文件中定义一些默认值,这样在进行证书相关操作时可以少输入很多内容。
如果不知道OpenSSL的配置文件在哪儿,可以通过 openssl version -d 来查找OpenSSL的相关文件。
sudo openssl version -d
(1)先将原有的配置文件备份,然后手动创建同名配置文件
sudo mv /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf-bak
(2)编辑配置文件,加入以下一些简单的配置
sudo vim /etc/ssl/openssl.cnf
# [ ca ]指定默认的 CA 配置区段,因为可能会存在多个 CA 配置区段,用于不同的目的或者不同的证书策略
[ ca ]
# 定义默认的CA设置部分名称
default_ca = CA_default
# [ CA_default ] 定义了关于证书颁发机构(CA)的默认设置和相关文件路径。
[ CA_default ]
# 定义CA的主目录。
dir = /etc/pki/CA
# 已签发的证书的存储位置
certs = $dir/certs
# 新证书的默认存放位置
new_certs_dir = $dir/newcerts
# 用于存储证书签发信息的数据库文件的位置
database = $dir/index.txt
# CA的证书位置
certificate = $dir/certs/cacert.pem
# CA的私钥位置
private_key = $dir/private/cakey.key
# 存储当前证书序列号的文件位置
serial = $dir/serial
# 默认证书有效期
default_days = 3650
# 默认使用的消息摘要算
default_md = sha256
# 决定是否保留从证书请求(CSR)中传入的Distinguished Name(DN)的顺序
preserve = no
# [ req ]定义了与生成证书请求文件(也称为Certificate Signing Request,简称CSR)相关的默认设置
[ req ]
# 生成新私钥时使用的默认位数
default_bits = 2048
# 是否在创建证书请求时提示用户输入详细信息
# no表示使用 openssl req 命令创建新的CSR或证书时,将不会被提示输入任何DN字段,会使用 [ dn ] 部分提供的默认值。
prompt = no
# 用于证书请求的默认消息摘要算法
default_md = sha256
# 告诉OpenSSL使用配置文件中的[ dn ]部分作为CSR的默认字段值
distinguished_name = dn
# [ dn ] 定义了默认的Distinguished Name(可分辨名称)属性和它们的值
# C:国家 ST:省 L:市 O:通常是一个公司或机构的全名 OU:组织内部的一个特定部门或单位
# CN:在 SSL/TLS 证书的上下文中通常表示证书意图保护的域名emailAddress:邮箱
[ dn ]
C = CN
ST = BeiJin
L = BeiJin
O = My Company
OU = My Organizational Unit
emailAddress = admin@mycompany.com
CN = mycompany.com
配置文件链接
4、自签名证书生成
(1)要生成自签名证书,首先得需要有私钥,所以第一步就是需要先生成私钥。
# -algorithm RSA: 指定密钥的类型为 RSA
openssl genpkey -algorithm RSA -out /etc/pki/CA/private/cakey.key
(2)根据生成得私钥创建一个新的根证书,使用这个证书来签署其它得证书
在配置文件中通过 certificate = $dir/certs/cacert.pem 指定了CA证书的位置,这里创建自签名证书的时候就要放到对应的位置才可以。
openssl req -key /etc/pki/CA/private/cakey.key -new -x509 -days 7300 -out /etc/pki/CA/certs/cacert.pem
至此,私有CA就算搭建完成了。
CA颁发证书
1、用户生成证书请求文件(CSR)
如果客户端想要CA给它颁发证书,首先就需要准备一个证书请求文件,CSR中包含公钥和请求者的标识信息(如:组织、位置、国家、域名等)
# 一般先创建一个目录存放相关文件
mkdir tom
# cd tom
# 一步到位生成私钥和CSR
sudo openssl req -new -keyout tom.key -out tom_req.csr -nodes
说明:
-
一般情况下,生成私钥的时候会要求输入一个密码,不输入的话可能会提示error,可以通过 -nodes 参数来不输入密码
-
这里是一步到位生成私钥和CSR,-keyout clientkey.pem 选项生成一个新的私钥,然后根据生成的私钥创建证书请求文件
-
因为我是直接在CA上生成的CSR,配置文件里面指定了请求者的标识信息(如:组织、位置、国家、域名等,所以这里没有提示输出。
2、CA接收用户的CSR
客户端将CSR生成后,需要交给CA,可以通过文件拷贝、远程传输都可以。
这里单独给客户的证书请求文件创建了一个目录,用于保存客户端传输过来的CSR文件。
mkdir /etc/pki/CA/csr
3、CA验证身份
CA会验证请求者的身份,例如发右键、打电话给请求者。
4、CA签发证书
CSR通过验证了,就使用其私钥为请求者的公钥签发一个证书。该证书有效地绑定了请求者的身份和其公钥。
sudo openssl ca -batch -in /etc/pki/CA/csr/tom_req.csr -out /etc/pki/CA/certs/tom.pem
说明:
-
通过 -bath参数实现签署证书时自动确认
-
如果初始化CA环境的时候,index.txt这个数据库文件不为空,那么此时签署证书不会成功,也不会有任何错误提示。
(5)证书生成后,返回给客户端,请求者可以将证书和其私钥一起使用
CA的几个特殊文件
在搭建好私有CA并且颁发证书后,可以看到除了原来的index.txt和serial,还生成了index.txt.attr、index.txt.old、serial.old文件
serial
serial这个文件包含下一个证书的序列号。每当一个新的证书被签发,这个数字会增加,确保每个证书都有一个唯一的序列号。
可以看到证书生成后,可以看到serial文件的内容递增了 1
ehigh@ubuntu:/etc/pki/CA$ cat serial
02
index.txt
这是一个数据库文件,用于追踪CA签发的所有证书。每一行代表一个证书,包括证书的状态(如V代表有效,R代表撤销等)、过期日期、序列号、证书的Distinguished Name等。签发新的证书或撤销现有的证书时,此文件会更新
index.txt内容说明
idnex.txt文件用于存储CA签发的所有证书,一行代表一个证书。
V 331028032625Z 01 unknown /C=CN/ST=BeiJin/O=My Company/OU=My Organizational Unit/CN=mycompany.com/emailAddress=admin@mycompany.com
-
第一列表示的就是证书的状态,V表示有效,如果是R表示已经被撤销了
-
第二列就是证书的过期日期,使用YYMMDDHHMMSSZ,最后的 Z 表示这是 UTC 时间。 331028032625Z表示证书的过期日期为 2033 年 10 月 28 日 03:26:25
-
第三列就是证书的序列号,这里是01
-
第四列是文件名,unknown 表示文件名未知或证书不存储在独立的文件中
-
第五列就是证书的主题,包括多个字段
默认情况下,相同主题的证书申请文件(CSR)只能申请一次证书,试图使用相同的主题重新签发证书会失败。因为我们是在配置文件里面指定了主题信息,又是私有CA,如果要实现相同主题重复申请证书,把index.txt.attr文件中的unique_subject = yes改为unique_subject = no就行了。
index.txt.attr
该文件包含了index.txt文件的一些属性,unique_subject = yes表示在index.txt数据库中的每个主题应该是唯一的,即不允许有两个具有相同主题的证书
ehigh@ubuntu:/etc/pki/CA$ cat index.txt.attr
unique_subject = yes
index.txt.old
存放上一个证书的数据库信息
例如:
# 因为这就是第一个证书,所以上一个证书为空
ehigh@ubuntu:/etc/pki/CA$ cat index.txt.old
serial.old
该文件存放上一个证书的编号信息
ehigh@ubuntu:/etc/pki/CA$ cat serial.old
01
注销证书
1、吊销证书
将证书标记为已吊销,证书吊销后index.txt数据库文件中关于该证书的条目会被自动更新,该证书相关的条目的标志会从 V (或其他状态) 更改为 R。(E:表示证书已过期 (Expired)。)
openssl ca -revoke 要注销的证书文件
2、生成新的CRL
这一步的作用是当有证书被吊销时,CA需要发布一个新的CRL,以便客户端和其他实体可以检查并知道哪些证书不再受信任。
通常当设置一个私有证书颁发机构 (CA) 并开始颁发证书时,还没有任何要吊销的证书,因此最初可能不会有CRL,如果开始吊销证书,就需要手动创建这个文件,crl文件的命名方式一般是crl.pem这种。
如果直接使用touch crl.pem只会创建一个空的文件。而一个真正的CRL文件包含了吊销证书的信息,并且由CA签名。所以我们要使用命令来生成这个文件。
# 证书吊销文件的路径是配置文件里面制定了的,所以不能乱放
openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem
常见后缀
虽然在Linux里面,文件的类型不是由文件后缀决定的,但是加上不同的后缀可以很好分辨文件的作用和进行管理。
-
.key:一般私钥就以 .key 结尾
-
.pem:新生成的证书一般以 .pem 结尾。pem是 Privacy Enhanced Mail 的缩写,是一种文件格式,可以包含任何类型的证书或密钥。这种格式的文件类容是BASE64编码显示的,并在开始和结束时由”—–BEGIN…”和”—–END…”标记包围。
-
.scr:证书请求文件使用csr结尾,csr是Certificate Signing Request的缩写
-
.crl:这是CA用于列出已被撤销的证书的文件常用的后缀,是Certificate Revocation List的缩写。
说明: 除了使用.pem后缀来标记一个证书文件外,还可以使用crt 或 .cer 来标记。
查看证书内容
有些时候需要确认证书的主题或颁发者,检查证书的有效期,还有当SSL/TLS设置出现问题时,检查证书可以帮助确定问题的原因时候,需要查看证书的内容来排查是否是证书或CSR文件引起的。
openssl x509 -in /path/file_name -noout -text
# -noout:表示不输出证书的编码
# text:显示证书的全部信息,包括主题、颁发者、有效期等
说明:
OpenSSL生成的证书是X.509类型的。X.509是一个标准,定义了公钥证书的结构和属性。当我们在日常语境中提到“SSL证书”或“TLS证书”时,我们实际上指的是遵循X.509标准的证书。
相关流程说明
CA颁发证书流程
上面我们知道了如何大家CA、以及使用CA对证书进行管理,还有用户申请证书的流程。现在我们可以来探讨CA颁发证书是什么样一个流程。
1、用户生成证书请求文件,证书请求文件包含了用户的公钥还有一些主题信息(组织、位置、国家、域名等等)
2、CA机构将用户的证书申请文件通过hash算法生成一个摘要
3、CA机构将生成的摘要进行加密(私钥加密)从而得到一个签名
4、将用户的公钥、CA生成的签名加上相关信息整合在一起就形成了一个数字证书
验证证书流程
例如服务器和客户端通信的时候,给了客户端一个证书,客户端如何验证这个证书是否有效。
1、 客户端明文接收服务端发送过来的证书
2、客户端提取证书中的签名,并使用CA的公钥对签名进行解密,得到原始的摘要信息。
3、 客户端使用相同的哈希算法对接收到的证书(从证书中提取出公钥、用户信息和其他相关信息)进行哈希运算,生成一个新的摘要。
4、 对比两个摘要是否一致,这样就实现了数据完整性的验证。
数据通信流程
像https这种,就是通过证书来实现安全数据传输的。
客户端:
-
客户端使用哈希算法对需要发送的数据生成一个摘要。这个摘要可以用来验证数据的完整性,确保在传输过程中没有被篡改。
-
客户端生成一个随机的对称密钥,并使用该密钥对要发送的数据进行加密。对称密钥加密速度快,适合加密大量数据。
-
客户端使用服务端的公钥(从证书中获取)对随机对称密钥进行加密。服务端的公钥可以确保只有服务端能够解密该对称密钥。
-
客户端将生成的摘要、加密后的数据以及加密后的随机对称密钥一起发送给服务端。
服务端:
-
服务端接收到客户端发送的数据后,使用私钥解密客户端发送的加密的随机对称密钥,以获得该对称密钥。
-
服务端使用获得的对称密钥对加密的数据进行解密,以恢复原始数据。
-
服务端使用相同的哈希算法对解密后的数据生成一个摘要。
-
服务端将生成的摘要与客户端发送的摘要进行比较。如果两个摘要相同,说明数据完整性没有受到篡改。