> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/blockchain_guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/blockchain_guide/05_crypto/pki.md).

# PKI 体系

按照 X.509 规范，公钥可以通过证书机制来进行保护，但证书的生成、分发、撤销等步骤并未涉及。

实际上，要实现安全地管理、分发证书需要遵循 PKI（Public Key Infrastructure）体系。该体系解决了证书生命周期相关的认证和管理问题。

需要注意，PKI 是建立在公私钥基础上实现安全可靠传递消息和身份确认的一个通用框架，并不代表某个特定的密码学技术和流程。实现了 PKI 规范的平台可以安全可靠地管理网络中用户的密钥和证书。目前包括多个具体实现和规范，知名的有 RSA 公司的 PKCS（Public Key Cryptography Standards）标准和 OpenSSL 等开源工具。

## PKI 基本组件

一般情况下，PKI 至少包括如下核心组件：

* CA（Certification Authority）：负责证书的颁发和吊销（Revoke），接收来自 RA 的请求，是最核心的部分；
* RA（Registration Authority）：对用户身份进行验证，校验数据合法性，负责登记，审核过了就发给 CA；
* 证书数据库：存放证书，多采用 X.500 系列标准格式。可以配合LDAP 目录服务管理用户信息。

其中，CA 是最核心的组件，主要完成对证书信息的维护。

常见的操作流程为，用户通过 RA 登记申请证书，提供身份和认证信息等；CA 审核后完成证书的制造，颁发给用户。用户如果需要撤销证书则需要再次向 CA 发出申请。

## 证书的签发

CA 对用户签发证书实际上是对某个用户公钥，使用 CA 的私钥对其进行签名。这样任何人都可以用 CA 的公钥对该证书进行合法性验证。验证成功则认可该证书中所提供的用户公钥内容，实现用户公钥的安全分发。

用户证书的签发通常应由用户自己生成公钥和私钥，然后 CA 对公钥内容进行签名（只有用户持有私钥）。对于公开信任的 TLS 服务器证书，CA/B Forum Baseline Requirements 明确禁止 CA 代表订阅者生成包含 `serverAuth` 或 `anyExtendedKeyUsage` 的证书密钥对，也禁止接受由该 CA 先前生成的密钥对。私有 PKI 中如确需密钥托管或代生成，必须有明确授权、用途边界和保护措施，且不适用于需要不可抵赖性的签名私钥。

前者情况下，用户一般会首先自行生成一个私钥和证书申请文件（Certificate Signing Request，即 csr 文件），该文件中包括了用户对应的公钥和一些基本信息，如通用名（common name，即 cn）、组织信息、地理位置等。CA 只需要对证书请求文件进行签名，生成证书文件，颁发给用户即可。整个过程中，用户可以保持私钥信息的私密性，不会被其他方获知（包括 CA 方）。

生成证书申请文件的过程并不复杂，用户可以很容易地使用开源软件 openssl 来生成 csr 文件和对应的私钥文件。

例如，安装 openssl 后可以执行如下命令来生成私钥和对应的证书请求文件：

```bash
$ openssl req -new -newkey rsa:2048 -sha256 -keyout private.key -out for_request.csr
Generating a 2048 bit RSA private key
................................................+++++
................................................+++++
writing new private key to 'private.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgets Pty Ltd]:Blockchain
Organizational Unit Name (eg, section) []:Dev
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:

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

生成过程中需要输入地理位置、组织、通用名等信息。生成的私钥和 csr 文件默认以 PEM 格式存储，内容为 base64 编码。

如生成的 csr 文件内容可能为：

```bash
$ cat for_request.csr
-----BEGIN CERTIFICATE REQUEST-----
...base64-encoded CSR...
-----END CERTIFICATE REQUEST-----
```

openssl 工具提供了查看 PEM 格式文件明文的功能，如使用如下命令可以查看生成的 csr 文件的明文：

```bash
$ openssl req -in for_request.csr -noout -text
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CN, ST=Beijing, L=Beijing, O=Blockchain, OU=Dev, CN=yeasy.github.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
                Modulus:
                    ...2048-bit modulus omitted...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
        ...signature omitted...
```

示例中使用 2048 位 RSA 和 SHA-256。1024 位 RSA 和 SHA-1 签名已不适合新的证书申请或签发：NIST SP 800-131A 将低于 2048 位的 RSA 签名生成列为不允许，SHA-1 也不应用于新的数字签名生成。

需要注意，用户自行生成私钥情况下，私钥文件一旦丢失，CA 方由于不持有私钥信息，无法进行恢复，意味着通过该证书中公钥加密的内容将无法被解密。

## 证书的吊销

证书超出有效期后会作废，用户也可以主动向 CA 申请吊销某证书文件。

由于 CA 无法强制收回已经颁发出去的数字证书，因此为了实现证书的作废，往往还需要维护一个吊销证书列表（Certificate Revocation List，CRL），用于记录已经吊销的证书序号。

因此，通常情况下，当对某个证书进行验证时，需要首先检查该证书是否已经记录在列表中。如果存在，则该证书无法通过验证。如果不在，则继续进行后续的证书验证过程。

为了方便同步吊销列表信息，IETF 提出了在线证书状态协议（Online Certificate Status Protocol，或 OCSP），支持该协议的服务可以实时在线查询吊销的证书列表信息。
