# X.509 证书认证

X.509 是一种标准的公钥证书格式，广泛用于互联网的安全通信中。EMQX 支持使用 X.509 证书进行 TLS/SSL 连接以及客户端/服务器双向认证，以实现更高级别的安全性保障。

## 工作原理

EMQX 允许客户端使用 X.509 证书进行 TLS/SSL 连接，并支持将证书信息与客户端进行绑定，以实现 X.509 证书认证。其使用与工作流程如下：

1. 签发服务端证书，为 EMQX 启用 TLS/SSL，并设置其为[双向认证](../../network/emqx-mqtt-tls.md#启用双向认证)。
2. 签发客户端证书，将证书与私钥文件烧录到设备中，并使用其进行 TLS/SSL 连接。
3. 客户端将在 TLS 握手阶段发送证书给服务器，以证明其身份的合法性。
4. EMQX 收到客户端的证书后，会对证书进行验证，以确认客户端的身份。
5. 如果验证通过，服务器会继续完成 TLS 握手，建立安全连接。

连接成功后，EMQX 支持将证书信息映射到客户端属性，实现证书与客户端的绑定。除此之外，还可以搭配其他应用层的认证方式，如 [JWT](./jwt.md)、[密码认证](./pwoverview.md)，实现多种认证方式的组合。

## 特性与优势

- **安全性**：X.509 提供了一种安全可靠的认证机制，通过使用数字证书和公钥加密技术，确保了通信的机密性、完整性和身份验证。它可以防止未经授权的设备接入网络或进行恶意操作。

- **互操作性**：X.509 是一种通用的标准，被广泛支持和采用。许多物联网设备都支持 X.509 证书的使用，这使得设备之间的认证和安全通信更加简单和可靠。

- **可扩展性**：X.509 可以支持大规模的物联网部署。它提供了灵活的证书链和证书管理机制，可以适应复杂的物联网环境，并支持大量设备和实体的身份验证。

- **可信任的第三方验证**：X.509 证书通常由可信任的证书颁发机构（Certificate Authority）签发，这些 CA 经过严格的安全审查和验证。设备可以使用由受信任的 CA 签发的证书，确保其身份和证书的合法性。

- **强大的加密算法支持**：X.509 支持广泛的加密算法和密钥长度，包括常用的对称加密算法和非对称加密算法。这使得物联网设备可以使用强大的密码学算法来保护通信的安全性。

- **灵活的证书配置和管理**：X.509 具有灵活的证书配置和管理选项。设备可以根据需求选择适当的证书属性和扩展字段，以满足特定的物联网应用需求。此外，证书的吊销和更新也可以通过证书管理机制进行有效管理。

这些特性使得 X.509 成为物联网安全的理想选择，EMQX 提供了完整的 X.509 证书认证支持，可以帮助您轻松实现物联网设备的安全接入和通信。

## 启用 X.509 证书认证

X.509 证书认证其实就是 TLS/SSL 双向认证，您可以参考 [启用双向认证](../../network/emqx-mqtt-tls.md#启用双向认证) 进行配置。

::: tip
X.509 证书认证是在密码认证与 JWT 认证前执行的。
:::

## 证书信息映射

EMQX 支持将 X.509 证书信息映射为用户名或客户端 ID，以实现证书与客户端的绑定。您可以通过 Dashboard 或配置文件进行设置。

您可以使用对端证书中的 CN、DN 等字段或整个证书内容来作为用户名。 目前支持的证书信息对应的释义如下：

- `cn`: 证书的 CN 字段
- `dn`: 证书的 DN 信息，格式为 `CN=xxx,OU=xxx,O=xxx,L=xxx,ST=xxx,C=xxx`
- `crt`: 证书的 DER 格式内容
- `pem`: DER 证书转换为 PEM 格式的内容
- `md5`: 取 DER 或 PEM 证书内容的 MD5 值

### 通过 Dashboard 设置

1. 打开 Dashboard，进入**管理** -> **MQTT 配置**页面，选择**通用**选项卡。
2. 在 MQTT 配置中找到以下配置项进行修改：
   - **使用对端证书作为用户名**：将 X.509 证书信息映射为用户名。
   - **使用对端证书作为客户端 ID**：将 X.509 证书信息映射为客户端 ID。

3. 点击**保存修改**按钮完成配置，新连接的客户端将按照配置的方式进行信息映射。

### 通过配置文件设置

1. 打开配置文件 `base.hocon`，根据您的安装方式，可能位于 `./etc` 或 `/etc/emqx/etc` 目录。
2. 配置文件中默认没有 MQTT 配置，添加以下配置覆盖默认值：

  ```bash
  mqtt {
    # 将证书信息作为客户端 ID
    peer_cert_as_clientid = "disabled" # "disabled" | "cn" | "dn" | "crt" | "pem" | "md5"
    # 将证书信息作为用户名
    peer_cert_as_username = "cn" # "disabled" | "cn" | "dn" | "crt" | "pem" | "md5"
  }
  ```
