Bootstrap

使用OpenSSL生成自己CA根证书,和使用CA根证书颁发二级证书

使用OpenSSL生成自己CA根证书,和使用CA根证书颁发二级证书

前言

需要在自己安装好Openssl,网上有很多攻略
本文是以grpc的证书认证为例,用生成的root.crt证书签发两个二级证书client.crtserver.crt

一、生成CA根证书

1.1 在证书存放文件夹下 新建 root.conf

写入内容如下:

[req]
default_bits = 2048
prompt = no
default_keyfile = root.key
distinguished_name = req_distinguished_name


[req_distinguished_name]
C=CN
ST=HuNan
L=ChangSha
O=HuNan University
OU=My Department
CN=root.grpc.io


[root_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign

这个配置文件主要用于生成证书签名请求(CSR,Certificate Signing Request)以及定义根证书的扩展信息,通常会配合 OpenSSL 等工具来创建自签名的根证书:

[req] 部分
此部分定义了证书请求生成过程中的一些全局设置:

  • default_bits = 2048
    • 规定了生成密钥对时默认使用的密钥长度为 2048 位。在密码学里,密钥长度是衡量加密强度的关键指标,2048 位的 RSA 密钥目前被认为能提供足够的安全性,可有效抵御常见的攻击手段。
  • prompt = no
    • 当设置为 no 时,意味着在生成证书请求的过程中,系统不会以交互式的方式提示用户输入相关信息。所有必要的信息都将从配置文件中预先指定的内容获取。
  • default_keyfile = root.key
    • 指定了默认的私钥文件名是 root.key。若在生成证书请求时没有特别指定私钥文件,系统就会使用这个文件名来处理私钥。
  • distinguished_name = req_distinguished_name
    • 表明证书中可分辨名称(Distinguished Name,DN)的信息将从配置文件里的 [req_distinguished_name] 部分获取。可分辨名称是用于唯一标识一个实体(如组织、个人等)的一组属性。

[req_distinguished_name] 部分
该部分详细定义了证书中可分辨名称的具体内容:

  • C=CN
    • C 代表国家(Country),CN 是中国的国家代码,这表明该证书所属实体位于中国。
  • ST=HuNan
    • ST 表示州或省份(State or Province),这里指定为湖南。
  • L=ChangSha
    • L 代表城市或地区(Locality),指定为长沙。
  • O=HuNan University
    • O 表示组织(Organization),这里指定为湖南大学,即该证书所属的组织名称。
  • OU=My Department
    • OU 代表组织单位(Organizational Unit),指定为 “My Department”,表示该证书所属组织内的具体部门。
  • CN=root.grpc.io
    • CN 是通用名称(Common Name),指定为 root.grpc.io,通常用于标识证书的主体,对于根证书来说,这是根证书的一个标识名称。

[root_ext] 部分
此部分定义了根证书的扩展信息,这些扩展信息为证书添加了额外的属性和约束:

  • basicConstraints = critical,CA:true
    • basicConstraints 是一个基本约束扩展,critical 表示这个扩展是必须被处理的,如果证书验证者不支持该扩展,则必须拒绝该证书。CA:true 明确表示该证书是一个证书颁发机构(CA)的证书,具备签发其他证书的权限。
  • keyUsage = critical,keyCertSign,cRLSign
    • keyUsage 是一个密钥使用扩展,同样 critical 表示该扩展必须被处理。keyCertSign 表示该证书的私钥可以用于签发其他证书,cRLSign 表示该私钥可以用于签发证书吊销列表(Certificate Revocation List,CRL)。

这个配置文件可用于生成一个自签名根证书的证书请求,同时为该根证书指定了必要的信息和扩展,以确保其具有作为根证书颁发机构的功能和权限。

1.2生成root秘钥,得到root.key

openssl genrsa -out root.key 4096
  • openssl:这是命令的基础,代表调用 OpenSSL 工具。OpenSSL 是一个开源的、功能强大的密码学工具包,提供了各种加密、解密、签名、验证等功能,在网络通信、安全认证等领域有广泛应用。
  • genrsa:这是 OpenSSL 的一个子命令,专门用于生成 RSA 私钥。它会根据指定的参数生成一个符合 RSA 算法的私钥。
  • -out root.key:这是一个选项,-out 用于指定输出文件的名称。在这里,生成的 RSA 私钥将被保存到名为 root.key 的文件中。如果当前目录下已经存在同名文件,该文件将被覆盖。
  • 4096:这是指定生成的 RSA 私钥的长度,单位是位(bit)。密钥长度是衡量 RSA 密钥安全性的一个重要指标,密钥长度越长,破解的难度就越大,安全性也就越高。4096 位的 RSA 密钥在当前被认为具有较高的安全性,能够抵御大多数已知的攻击手段。

1.3 生成root证书签发请求,得到root.csr

openssl req -new -sha256 -out root.csr -key root.key -config root.conf

该命令的主要作用是基于已有的私钥(root.key),结合配置文件(root.conf)中的信息,生成一个新的证书签名请求文件(root.csr),并使用 SHA - 256 哈希算法对请求内容进行签名。

openssl
这是 OpenSSL 工具的调用命令。OpenSSL 是一个强大的开源密码学工具包,提供了各种加密、安全相关的功能,广泛用于生成密钥、证书,进行加密通信等。

req
req 是 OpenSSL 的一个子命令,专门用于处理证书签名请求相关的操作,包括生成、查看和验证 CSR。

-new
此选项表示要创建一个新的证书签名请求。当你需要向证书颁发机构(CA)申请新证书时,就需要生成一个新的 CSR 并提交给 CA。

-sha256
指定在生成 CSR 时使用 SHA - 256(Secure Hash Algorithm 256 - bit)哈希算法。SHA - 256 是一种常用的安全哈希算法,用于对数据进行哈希计算,生成一个固定长度的哈希值,确保数据的完整性和真实性。在生成 CSR 时,会使用该算法对请求中的信息进行哈希处理,然后用私钥对哈希值进行签名。
-out root.csr
-out 选项用于指定输出文件的名称。这里将生成的证书签名请求保存为 root.csr 文件。CSR 文件包含了请求者的公钥以及一些身份信息,如组织名称、域名等,将被发送给 CA 用于证书申请。
-key root.key
-key 选项用于指定生成 CSR 时所使用的私钥文件。这里使用的是 root.key 文件中的私钥。私钥用于对 CSR 中的信息进行签名,确保 CSR 的完整性和真实性。在生成 CSR 之前,需要先使用 openssl genrsa 等命令生成相应的私钥。
-config root.conf
-config 选项指定了用于生成 CSR 的配置文件。root.conf 文件中包含了生成 CSR 所需的各种信息,如可分辨名称(Distinguished Name)、扩展信息等。通过配置文件,可以方便地指定这些信息,避免在命令行中逐个输入。

1.4 生成root根证书,得到root.crt

openssl x509 -req -in root.csr -out root.crt -signkey root.key -days 3650 -extfile root.conf -extensions root_ext

该命令主要用于根据已有的证书签名请求(CSR)文件,结合私钥对其进行签名,从而生成一个自签名的 X.509 证书。自签名证书是指由自己的私钥对证书进行签名,而非由权威证书颁发机构(CA)签名。

openssl x509

  • openssl 是一个强大的开源密码学工具包,用于处理各种加密和安全相关任务。
  • x509 是 OpenSSL 中的一个子命令,专门用于处理 X.509 格式的证书,X.509 是一种广泛使用的证书标准。

-req
此选项表明输入的文件是一个证书签名请求(CSR)。root.csr 文件包含了证书申请者的公钥以及一些身份信息,等待被签名以生成正式的证书。
-in root.csr

  • -in 用于指定输入文件的路径。这里指定输入的文件为 root.csr,即之前生成的证书签名请求文件。
    -out root.crt
  • -out 用于指定输出文件的路径。命令执行后,生成的自签名证书将被保存为 root.crt 文件。
    -signkey root.key
  • -signkey 用于指定用于签名的私钥文件。这里使用 root.key 私钥对 root.csr 中的信息进行签名,以证明证书的真实性和完整性。该私钥应该与 CSR 中对应的公钥是一对密钥对。

-days 3650

  • -days 选项用于指定生成的证书的有效期,单位为天。这里设置为 3650 天,即证书从颁发之日起,有效期为 10 年。

-extfile root.conf

  • -extfile 用于指定包含证书扩展信息的配置文件。root.conf 文件中可以定义一些额外的证书扩展字段,如基本约束、密钥使用方式等。

-extensions root_ext

  • -extensions 用于指定从配置文件(root.conf)中读取哪个部分的扩展信息。这里指定为 root_ext,意味着将从 root.conf 文件中读取 [root_ext] 部分的配置内容,并将其添加到生成的证书中。

1.5 检查root.crt是否是一个根证书

截止到这里你应该在你的命令所在的文件下生成了好几个文件,包括root.key root.csr root.crt root.srl以及自己定义的root.conf这几个文件,而root.crt就是我们所需要的根证书。那么这么就要判断一下root.crt文件到底是不是根证书。接下来需要通过这个命令来判断。

openssl x509 -in root.crt -text -noout

如果有

 X509v3 Basic Constraints: critical                                                                          
                CA:TRUE

也就是 CA:TRUE 则表示这个就是根证书了。

二、使用root.crt生成二级证书server.crt

2.1.在证书存放文件夹下,新建server.conf

[req]
default_bits = 2048
default_keyfile = server.key
distinguished_name = req_distinguished_name
req_extensions = req_ext
[req_distinguished_name]
countryName                 = CN
countryName_default         = CN
stateOrProvinceName         = HuNan
stateOrProvinceName_default = HuNan
localityName                = ChangSha
localityName_default        = ChangSha
organizationName            = HuNan University
organizationName_default    = HuNan University
commonName = server.grpc.io
commonName_default = server.grpc.io
commonName_max  = 64

[req_ext]
subjectAltName = DNS:server.grpc.io

[req] 部分
这部分定义了生成证书签名请求时的全局配置选项。

  • default_bits = 2048
    • 此配置指定了生成 RSA 密钥对时默认使用的密钥长度为 2048 位。在密码学中,密钥长度是衡量加密强度的关键指标,2048 位的 RSA 密钥目前被认为具有足够的安全性,能抵御常见的攻击。
  • default_keyfile = server.key
    • 该配置指定了默认使用的私钥文件名为 server.key。在生成证书签名请求时,如果没有特别指定私钥文件,就会使用这个文件中的私钥。
  • distinguished_name = req_distinguished_name
    • 此设置表明证书的可分辨名称(Distinguished Name, DN)信息将从配置文件中的 [req_distinguished_name] 部分获取。可分辨名称是用于唯一标识一个实体(如组织、个人等)的一组属性。
  • req_extensions = req_ext
    • 这意味着在生成证书签名请求时,将使用 [req_ext] 部分定义的扩展信息。

[req_distinguished_name] 部分
这部分详细定义了证书的可分辨名称(DN)信息。

  • countryName = CNcountryName_default = CN
    • countryName 表示国家代码,CN 代表中国。countryName_default 是默认值,两者一致确保了在生成 CSR 时国家信息的准确性。
  • stateOrProvinceName = HuNanstateOrProvinceName_default = HuNan
    • stateOrProvinceName 表示州或省份,这里是湖南。同样,stateOrProvinceName_default 提供默认值。
  • localityName = ChangShalocalityName_default = ChangSha
    • localityName 表示城市或地区,指定为长沙,localityName_default 为默认值。
  • organizationName = HuNan UniversityorganizationName_default = HuNan University
    • organizationName 表示组织名称,这里是湖南大学,organizationName_default 为默认值。
  • commonName = server.grpc.iocommonName_default = server.grpc.io
    • commonName 是通用名称,通常用于标识证书的主体,这里是 server.grpc.iocommonName_default 为默认值。
  • commonName_max = 64
    • 该配置限制了通用名称的最大长度为 64 个字符,确保通用名称不会过长。

[req_ext] 部分
这部分定义了证书签名请求的扩展信息。

  • subjectAltName = DNS:server.grpc.io
    • subjectAltName 是一个重要的证书扩展字段,用于指定证书的备用名称。这里指定了一个 DNS 名称 server.grpc.io,表示该证书不仅可以用于 commonName 中指定的主体,还可以用于这个备用的 DNS 名称。在现代的 TLS/SSL 通信中,subjectAltName 字段非常重要,因为浏览器等客户端通常会检查这个字段来验证证书的有效性。

关于root.conf server.conf[req_distinguished_name]区别,这两个都可以 root.conf 感觉用的字母简写,server.conf使用的是全写,并配有默认值。个人感觉server.conf更详细一些,比较友好

[req_distinguished_name]
C=CN
ST=HuNan
L=ChangSha
O=HuNan University
OU=My Department
CN=root.grpc.io
[req_distinguished_name]
countryName                 = CN
countryName_default         = CN
stateOrProvinceName         = HuNan
stateOrProvinceName_default = HuNan
localityName                = ChangSha
localityName_default        = ChangSha
organizationName            = HuNan University
organizationName_default    = HuNan University
commonName = server.grpc.io
commonName_default = server.grpc.io
commonName_max  = 64

2.2 生成秘钥,得到server.key

openssl genrsa -out server.key 2048

2.3 生成证书签发请求,得到server.csr

openssl req -new -sha256 -out server.csr -key server.key -config server.conf

因为配置文件中给了值,所以只需要enter回车即可,如:

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.                                                                         
-----                                                                                                                   
CN [CN]:                                                                                                                
HuNan [HuNan]:                                                                                                          
ChangSha [ChangSha]:                                                                                                    
HuNan University [HuNan University]:                                                                                    
server.grpc.io [server.grpc.io]:  

2.4 用CA证书生成服务端证书,得到server.crt

openssl x509 -req -days 3650 -CA root.crt -CAkey root.key -CAcreateserial -in server.csr -out server.crt -extensions req_ext -extfile server.conf

该命令的核心功能是使用根证书(root.crt)及其对应的私钥(root.key)对服务器的证书签名请求(server.csr)进行签名,从而生成一个有效期为 3650 天的服务器证书(server.crt),同时应用 server.conf 配置文件中 req_ext 部分定义的证书扩展信息。

openssl x509

  • openssl 是一个强大的开源密码学工具包,用于处理各种加密和安全相关任务。
  • x509 是 OpenSSL 的一个子命令,专门用于处理 X.509 格式的证书,X.509 是一种广泛使用的公钥证书标准。

-req
此选项表明输入的文件是一个证书签名请求(CSR)。server.csr 文件包含了服务器的公钥以及一些身份信息,等待由 CA 进行签名以生成正式的证书。

-days 3650
指定生成的证书的有效期为 3650 天,即从证书颁发之日起,该证书在接下来的 10 年内有效。

-CA root.crt
指定用于签名的证书颁发机构(CA)的证书文件为 root.crt。CA 证书是信任链的基础,用于验证服务器证书的真实性。

-CAkey root.key
指定与 CA 证书对应的私钥文件为 root.key。在签名过程中,CA 使用这个私钥对服务器的 CSR 进行签名,以证明服务器证书的合法性。

-CAcreateserial
如果指定了这个选项,OpenSSL 会自动创建一个序列号文件(通常名为 root.srl),并为新生成的证书分配一个唯一的序列号。序列号用于唯一标识每个证书,在证书的管理和验证过程中非常重要。

-in server.csr
指定输入的证书签名请求文件为 server.csr,这是服务器在申请证书时生成的文件,包含了服务器的公钥和相关身份信息。

-out server.crt
指定输出的证书文件名为 server.crt。执行该命令后,生成的经过 CA 签名的服务器证书将保存到这个文件中。

-extensions req_ext
指定要应用的证书扩展信息来自配置文件中的 [req_ext] 部分。证书扩展可以为证书添加额外的属性和功能,如指定证书的用途、添加备用域名等。

-extfile server.conf
指定包含证书扩展信息的配置文件为 server.conf。OpenSSL 会从这个文件中读取 [req_ext] 部分的内容,并将其应用到生成的服务器证书中。

2.5 验证得到server.crt是否是root.crt根证书签发的

此时文件夹下面的server.crt就是由root.crt根证书签发的,那么需要如何判断是否真的由root.crt根证书签发的,需要如下命令。

openssl verify -verbose -CAfile root.crt server.crt

如果能得到

server.crt: OK 

则表明由root.crt根证书签发的server.crt二级证书成功

三、使用root.crt生成二级证书client.crt

生成二级证书client.crt和第二章节的类似

3.1.在证书存放文件夹下,新建client.conf

[req]
default_bits = 2048
default_keyfile = client.key
distinguished_name = req_distinguished_name
req_extensions = req_ext
[req_distinguished_name]
countryName                 = CN
countryName_default         = CN
stateOrProvinceName         = HuNan
stateOrProvinceName_default = HuNan
localityName                = ChangSha
localityName_default        = ChangSha
organizationName            = HuNan University
organizationName_default    = HuNan University
commonName = client.grpc.io
commonName_default = client.grpc.io
commonName_max  = 64

[req_ext]
subjectAltName = DNS:client.grpc.io

3.2 生成秘钥,得到client.key

openssl genrsa -out client.key 2048

3.3 生成证书签发请求,得到client.csr

openssl req -new -sha256 -out client.csr -key client.key -config client.conf

3.4 用CA证书生成服务端证书,得到client.crt

openssl x509 -req -days 3650 -CA root.crt -CAkey root.key -CAcreateserial -in client.csr -out client.crt -extensions req_ext -extfile client.conf

3.5 验证得到client.crt是否是root.crt根证书签发的

此时文件夹下面的client.crt就是由root.crt根证书签发的,那么需要如何判断是否真的由root.crt根证书签发的,需要如下命令。

openssl verify -verbose -CAfile root.crt client.crt

如果能得到

client.crt: OK 

则表明由root.crt根证书签发的client.crt二级证书成功

4.总结

本来参考书别人的博客想做一下grpc的双向证书认证,发现在客户端运行代码总是无法识别根证书,摸索才发现我生成的根证书就不能签发 证书,所以才写下此篇博客记录一下,仅供参考!

;