ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

创建私有证书颁发机构

2022-01-22 23:01:35  阅读:208  来源: 互联网

标签:证书 私有 CA 颁发 ocsp root ca OCSP


本文是对https://www.feistyduck.com/library/openssl-cookbook/online/ch-openssl.html#openssl-private-ca的翻译

创建私有证书颁发机构

如果您想建立自己的 CA,您需要的一切都已包含在 OpenSSL 中。 用户界面纯粹是基于命令行的,因此对用户不是很友好,但这可能会更好。 经历这个过程很有教育意义,因为它迫使你思考每一个方面,甚至是最小的细节。

尽管还有其他原因,设置私有 CA 的教育意义是我建议这样做的主要原因。 基于 OpenSSL 的 CA,尽管它可能很粗糙,但可以很好地满足个人或小团队的需求。 例如,在开发环境中使用私有 CA 比在任何地方都使用自签名证书要好得多。 同样,提供双重身份验证的客户端证书可以显着提高敏感 Web 应用程序的安全性。

运行私有 CA 的最大挑战不是设置所有内容,而是保持基础架构的安全。 例如,根密钥必须保持离线,因为所有安全都依赖于它。 另一方面,CRLs 和 OCSP 响应者证书必须定期刷新,这需要使根联机。

在阅读本节时,您将创建两个配置文件:一个用于控制根 CA (root-ca.conf),另一个用于控制从属 CA (sub-ca.conf)。 虽然您应该可以按照我的说明从头开始做所有事情,但您也可以从我的 GitHub 帐户下载配置文件模板。20后一种方法可以节省您一些时间,但前一种方法可以让您更好地理解所涉及的工作。

特性和限制

在本节的其余部分,我们将创建一个与公共 CA 结构相似的私有 CA。 将有一个根 CA,可以从中创建其他从属 CA。 我们将通过 CRL 和 OCSP 响应程序提供撤销信息。 为了使根 CA 保持离线状态,OCSP 响应者将拥有自己的身份。 这不是您可以拥有的最简单的私有 CA,但它是可以正确保护的。 作为奖励,从属 CA 将在技术上受到限制,这意味着它只能为允许的主机名颁发证书。

设置完成后,必须将根证书安全地分发给所有预期的客户端。 一旦根就位,您就可以开始颁发客户端和服务器证书。 这种设置的主要限制是 OCSP 响应器主要是为测试而设计的,只能用于较轻的负载。

创建根 CA

创建一个新的 CA 涉及几个步骤:配置、创建目录结构和初始化密钥文件,最后生成根密钥和证书。 本节介绍流程以及常见的 CA 操作。

根 CA 配置

在我们实际创建 CA 之前,我们需要准备一个配置文件 (root-ca.conf),它将准确地告诉 OpenSSL 我们希望如何设置。 在正常使用期间,大多数时候不需要配置文件,但在涉及复杂操作(例如创建根 CA)时,它们是必不可少的。 OpenSSL 配置文件功能强大; 在您继续之前,我建议您熟悉它们的功能(命令行上的 man config)。

配置文件的第一部分包含一些基本的 CA 信息,例如名称和基本 URL,以及 CA 专有名称的组成部分。 因为语法很灵活,信息只需要提供一次:

[default]
name                    = root-ca
domain_suffix           = example.com
aia_url                 = http://$name.$domain_suffix/$name.crt
crl_url                 = http://$name.$domain_suffix/$name.crl
ocsp_url                = http://ocsp.$name.$domain_suffix:9080
default_ca              = ca_default
name_opt                = utf8,esc_ctrl,multiline,lname,align

[ca_dn]
countryName             = "GB"
organizationName        = "Example"
commonName              = "Root CA"

第二部分直接控制 CA 的操作。 有关每个设置的完整信息,请参阅 ca 命令的文档(命令行上的 man ca)。 大多数设置是不言自明的; 我们主要告诉 OpenSSL 我们要将文件保存在哪里。 因为这个根 CA 将仅用于下级 CA 的颁发,所以我选择让证书有效期为 10 年。 对于签名算法,默认使用安全的 SHA256。

配置默认策略 (policy_c_o_match),以便从该 CA 颁发的所有证书都具有与 CA 匹配的 countryName 和 organizationName 字段。 公共 CA 通常不会这样做,但它适用于私有 CA:

[ca_default]
home                    = .
database                = $home/db/index
serial                  = $home/db/serial
crlnumber               = $home/db/crlnumber
certificate             = $home/$name.crt
private_key             = $home/private/$name.key
RANDFILE                = $home/private/random
new_certs_dir           = $home/certs
unique_subject          = no
copy_extensions         = none
default_days            = 3650
default_crl_days        = 365
default_md              = sha256
policy                  = policy_c_o_match

[policy_c_o_match]
countryName             = match
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

第三部分包含 req 命令的配置,该命令仅在创建自签名根证书期间使用一次。 最重要的部分在扩展中:basicConstraints 扩展表明证书是一个 CA,keyUsage 包含此场景的适当设置:

[req]
default_bits            = 4096
encrypt_key             = yes
default_md              = sha256
utf8                    = yes
string_mask             = utf8only
prompt                  = no
distinguished_name      = ca_dn
req_extensions          = ca_ext

[ca_ext]
basicConstraints        = critical,CA:true
keyUsage                = critical,keyCertSign,cRLSign
subjectKeyIdentifier    = hash

配置文件的第四部分包含在构建由根 CA 颁发的证书期间将使用的信息。 如 basicConstraints 扩展所示,所有证书都是 CA,但我们将 pathlen 设置为零,这意味着不允许进一步的从属 CA。

所有从属 CA 都将受到限制,这意味着它们颁发的证书将仅对域名子集和受限用途有效。 首先,extendedKeyUsage 扩展只指定了clientAuth 和serverAuth,即TLS 客户端和服务器认证。 其次,nameConstraints 扩展将允许的主机名仅限于 example.com 和 example.org 域名。 从理论上讲,此设置使您能够将下级 CA 的控制权交给其他人,但仍然可以安全地知道他们不能为任意主机名颁发证书。 如果您愿意,您可以将每个从属 CA 限制在一个小的域名称空间中。 排除这两个 IP 地址范围的要求来自 CA/浏览器论坛的基线要求,其中定义了技术受限的从属 CA。21

在实践中,名称约束并不完全实用,因为一些主要平台目前不识别 nameConstraints 扩展。 如果您将此扩展标记为关键,则此类平台将拒绝您的证书。 如果您不将其标记为关键(如示例中所示),您将不会遇到此类问题,但是其他一些平台不会强制执行它。

[sub_ca_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:true,pathlen:0
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth,serverAuth
keyUsage                = critical,keyCertSign,cRLSign
nameConstraints         = @name_constraints
subjectKeyIdentifier    = hash

[crl_info]
URI.0                   = $crl_url

[issuer_info]
caIssuers;URI.0         = $aia_url
OCSP;URI.0              = $ocsp_url

[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

配置的第五部分也是最后一部分指定要与证书一起用于 OCSP 响应签名的扩展。 为了能够运行 OCSP 响应程序,我们生成一个特殊证书并将 OCSP 签名能力委托给它。 此证书不是 CA,您可以从扩展中看到:

[ocsp_ext]
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
extendedKeyUsage        = OCSPSigning
keyUsage                = critical,digitalSignature
subjectKeyIdentifier    = hash

根 CA 目录结构

下一步是创建上一节中指定的目录结构,并初始化一些将在 CA 操作期间使用的文件:

$ mkdir root-ca
$ cd root-ca
$ mkdir certs db private
$ chmod 700 private
$ touch db/index
$ openssl rand -hex 16  > db/serial
$ echo 1001 > db/crlnumber

使用以下子目录:

certs/
证书存储; 新证书将在颁发时放置在这里。

db/
此目录用于证书数据库(索引)和保存下一个证书和 CRL 序列号的文件。 OpenSSL 将根据需要创建一些附加文件。

private/
该目录将存储私钥,一个用于 CA,另一个用于 OCSP 响应者。 重要的是没有其他用户可以访问它。 (事实上​​,如果您要认真对待 CA,存储根材料的机器应该只有最少数量的用户帐户。)

注意
在创建新的 CA 证书时,使用随机数生成器初始化证书序列号很重要,就像我在本节中所做的那样。 如果您最终创建和部署了多个具有相同专有名称的 CA 证书,这将非常有用(如果您犯了错误并需要重新开始,这很常见); 将避免冲突,因为证书将具有不同的序列号。

根 CA 生成

我们采取两个步骤来创建根 CA。 首先,我们生成密钥和 CSR。 当我们使用 - config 开关时,将从配置文件中获取所有必要的信息:

$ openssl req -new \
    -config root-ca.conf \
    -out root-ca.csr \
    -keyout private/root-ca.key

第二步,我们创建一个自签名证书。 -extensions 开关指向配置文件中的 ca_ext 部分,该部分激活适用于根 CA 的扩展:

$ openssl ca -selfsign \
    -config root-ca.conf \
    -in root-ca.csr \
    -out root-ca.crt \
    -extensions ca_ext

数据库文件的结构

db/index 中的数据库是一个包含证书信息的明文文件,每行一个证书。 在创建根 CA 之后,它应该只包含一行:

V    240706115345Z        1001    unknown    /C=GB/O=Example/CN=Root CA

每行包含由制表符分隔的六个值:

  1. 状态标志(V 为有效,R 为已撤销,E 为过期)
  2. 到期日期(YYMMDDHHMMSSZ 格式)
  3. 撤销日期或未撤销则为空
  4. 序列号(十六进制)
  5. 文件位置或未知(如果不知道)
  6. 专有名称

根 CA 操作

要从新 CA 生成 CRL,请使用 ca 命令的 -gencrl 开关:

$ openssl ca -gencrl \
    -config root-ca.conf \
    -out root-ca.crl

要颁发证书,请使用所需参数调用 ca 命令。 重要的是-extensions 开关指向配置文件中的正确部分(例如,您不想创建另一个根CA)。

$ openssl ca \
    -config root-ca.conf \
    -in sub-ca.csr \
    -out sub-ca.crt \
    -extensions sub_ca_ext

要撤销证书,请使用 ca 命令的 -revoke 开关; 您需要有一份您希望撤销的证书的副本。 因为所有的证书都存放在 certs/ 目录下,所以只需要知道序列号即可。 如果您有专有名称,则可以在数据库中查找序列号。

为 -crl_reason 开关中的值选择正确的原因。 该值可以是以下之一:unspecified、keyCompromise、CACompromise、affiliationChanged、superseded、cessationOfOperation、certificateHold 和 removeFromCRL。

$ openssl ca \
    -config root-ca.conf \
    -revoke certs/1002.pem \
    -crl_reason keyCompromise

为 OCSP 签名创建证书

首先,我们为 OCSP 响应者创建一个密钥和 CSR。 这两个操作与任何非 CA 证书一样完成,这就是我们不指定配置文件的原因:

$ openssl req -new \
    -newkey rsa:2048 \
    -subj "/C=GB/O=Example/CN=OCSP Root Responder" \
    -keyout private/root-ocsp.key \
    -out root-ocsp.csr

其次,使用根 CA 颁发证书。 -extensions 开关的值指定 ocsp_ext,它确保设置了适合 OCSP 签名的扩展。 我将新证书的生命周期缩短到 365 天(从默认的 3,650 天)。 因为这些 OCSP 证书不包含吊销信息,所以它们不能被吊销。 因此,您希望尽可能缩短生命周期。 假如您准备以一个频率生成新的证书,30 天是一个不错的选择:

$ openssl ca \
    -config root-ca.conf \
    -in root-ocsp.csr \
    -out root-ocsp.crt \
    -extensions ocsp_ext \
    -days 30

现在您已准备好启动 OCSP 响应程序。 对于测试,您可以在根 CA 所在的同一台机器上进行。 但是,对于生产环境,您必须将 OCSP 响应者密钥和证书移到其他地方:

$ openssl ocsp \
    -port 9080
    -index db/index \
    -rsigner root-ocsp.crt \
    -rkey private/root-ocsp.key \
    -CA root-ca.crt \
    -text

您可以使用以下命令行测试 OCSP 响应程序的操作:

$ openssl ocsp \
    -issuer root-ca.crt \
    -CAfile root-ca.crt \
    -cert root-ocsp.crt \
    -url http://127.0.0.1:9080

在输出中,verify OK 表示签名已正确验证,good 表示证书尚未被吊销。

Response verify OK
root-ocsp.crt: good
        This Update: Jul  9 18:45:34 2014 GMT

创建从属 CA

从属 CA 的生成过程很大程度上与根 CA 的过程相同。 在本节中,我将仅在适当的地方强调差异。 有关其他所有内容,请参阅上一节。

从属 CA 配置

要为从属 CA 生成配置文件 (sub-ca.conf),请从我们用于根 CA 的文件开始,并进行本节中列出的更改。 我们将名称更改为 sub-ca 并使用不同的专有名称。 我们会将 OCSP 响应程序放在不同的端口上,但这只是因为 ocsp 命令不支持虚拟主机。 如果您为 OCSP 响应程序使用了适当的 Web 服务器,则可以完全避免使用特殊端口。 新证书的默认有效期为 365 天,我们将每 30 天生成一次新的 CRL。

将 copy_extensions 更改为 copy 意味着来自 CSR 的扩展将被复制到证书中,但前提是它们尚未在我们的配置中设置。 通过此更改,准备 CSR 的任何人都可以将所需的替代名称放入其中,从中提取的信息将被提取并放入证书中。 此功能有些危险(您允许其他人对证书中的内容进行有限的直接控制),但我认为它适用于较小的环境:

[default]
name                    = sub-ca
ocsp_url                = http://ocsp.$name.$domain_suffix:9081

[ca_dn]
countryName             = "GB"
organizationName        = "Example"
commonName              = "Sub CA"

[ca_default]
default_days            = 365
default_crl_days        = 30
copy_extensions         = copy

在配置文件的末尾,我们将添加两个新配置节,分别用于客户端证书和服务器证书。 唯一的区别在于 keyUsage 和 extendedKeyUsage 扩展。 请注意,我们指定了 basicConstraints 扩展,但将其设置为 false。 我们这样做是因为我们从 CSR 复制扩展。 如果我们不考虑这个扩展,我们最终可能会使用 CSR 中指定的扩展:

[server_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth,serverAuth
keyUsage                = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier    = hash

[client_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth
keyUsage                = critical,digitalSignature
subjectKeyIdentifier    = hash

对配置文件满意后,按照与根 CA 相同的过程创建目录结构。 只需使用不同的目录名称,例如 sub-ca。

从属 CA 生成

和根 CA 一样,我们采取两个步骤来创建从属 CA。 首先,我们生成密钥和 CSR。 当我们使用 -config 开关时,所有必要的信息都将从配置文件中获取。

$ openssl req -new \
    -config sub-ca.conf \
    -out sub-ca.csr \
    -keyout private/sub-ca.key

第二步,我们让根 CA 颁发证书。 -extensions 开关指向配置文件中的 sub_ca_ext 部分,该部分激活适用于从属 CA 的扩展。

$ openssl ca \
    -config root-ca.conf \
    -in sub-ca.csr \
    -out sub-ca.crt \
    -extensions sub_ca_ext

从属 CA 操作

要颁发服务器证书,请在 -extensions 开关中指定 server_ext 时处理 CSR:

$ openssl ca \
    -config sub-ca.conf \
    -in server.csr \
    -out server.crt \
    -extensions server_ext

要颁发客户端证书,请在 -extensions 开关中指定 client_ext 时处理 CSR:

$ openssl ca \
    -config sub-ca.conf \
    -in client.csr \
    -out client.crt \
    -extensions client_ext

注意
当请求新证书时,其所有信息将在操作完成之前提供给您进行验证。 您应该始终确保一切都是合宜的,尤其是当您正在使用其他人准备的 CSR 时。 请特别注意证书专有名称以及 basicConstraints 和 subjectAlternativeName 扩展。

CRL 生成和证书吊销与根 CA 相同。 OCSP 响应器唯一不同的是端口。 从属 CA 应改为使用 9081。 建议响应者使用自己的证书,这样可以避免将从属 CA 保留在公共服务器上。


[20] OpenSSL CA configuration templates (Bulletproof TLS and PKI GitHub repository, retrieved 20 October 2021)
[21] Baseline Requirements (The CA/Browser Forum, retrieved 9 July 2014)

标签:证书,私有,CA,颁发,ocsp,root,ca,OCSP
来源: https://blog.csdn.net/doushi/article/details/122639255

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有