# 基于MQTT.fx的X.509证书接入
本文档以MQTT.fx为例，介绍以MQTT原生协议接入物联网平台。MQTT.fx是目前主流的MQTT客户端，可以快速验证是否可以与物联网平台服务交互发布或订阅消息。
X.509是一种用于通信实体鉴别的数字证书，物联网平台支持设备使用自己的X.509证书进行认证鉴权。使用X.509认证技术时，设备无法被仿冒，避免了密钥被泄露的风险。
#### 前提条件
- 已注册华为云官方账号。未注册可单击[注册页面](https://reg.huaweicloud.com/registerui/public/custom/register.html#/register)完成注册。
- 已完成实名制认证。未完成可在华为云上单击[实名认证](https://account.huaweicloud.com/usercenter/#/accountindex/realNameAuth)完成认证，否则无法使用设备接入功能。
- 已开通设备接入服务。未开通则访问[设备接入服务](https://www.huaweicloud.com/product/iothub.html)，单击[管理控制台](https://console.huaweicloud.com/iotdm/#/dm-portal/home)后开通该服务。
 
#### 限制说明
- 当前只有通过MQTT接入的设备支持使用X.509证书进行设备身份认证。
- 每个用户最多上传100个设备CA证书。
 
#### X509认证步骤
- 证书双向认证完整业务流程为： ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001484852324.png "点击放大")
  
- 证书双向认证过程为： ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001484532288.png "点击放大")
  
 
#### 获取设备接入信息
在设备接入服务控制台获取设备接入平台所需的信息。
1. 访问[设备接入服务](https://www.huaweicloud.com/product/iothub.html)，单击[管理控制台](https://console.huaweicloud.com/iotdm/#/dm-portal/home)进入控制台。
2. 单击[管理控制台](https://console.huaweicloud.com/iotdm/#/dm-portal/home)进入控制台，单击左侧导航栏的"总览"，单击"实例基本信息 - 接入信息"查看设备接入信息，记录域名和端口。
   
   图1总览-获取接入信息   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002510383014.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   针对不支持用域名接入的设备，通过在cmd命令框中执行"ping 域名"获取IP地址，用IP地址接入平台。由于IP地址不固定，您需要将IP地址做成可配置项。
   
   
 
 #### 创建产品
1. 单击左侧导航栏"产品"，单击页面左侧的"创建产品"。 
   图2产品-创建产品   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002358714305.png "点击放大")
   
   
2. 根据页面提示填写参数，然后单击"确定"。 
   
   |                                                                                            **基本信息**                                                                                            ||
   |---|---|
   | 所属资源空间 | 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下，下拉选择所属的资源空间。如无对应的资源空间，请先创建[资源空间](https://support.huaweicloud.com/usermanual-iothub/iot_01_0006.html)。 |
   | 产品名称   | 自定义。支持字母、数字、下划线（_）、连字符（-）的字符组合。                                                                                                          |
   | 协议类型   | 选择MQTT。                                                                                                                                   |
   | 数据格式   | 选择JSON。                                                                                                                                  |
   | 所属行业    | 请根据实际情况选择。                                                                                                                              |
   | 设备类型     | 请根据实际情况选择。                                                                                                                              |
   | 高级配置                                                                                                                                                                                            ||
   | 产品ID    | 定制ProductID，用于唯一标识一个产品。如果携带此参数，平台将产品ID设置为该参数值；如果不携带此参数，产品ID在物联网平台创建产品后由平台分配获得。                                                           |
      
   图3创建产品-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981306829.png "点击放大")
   
   
 
#### 开发产品模型
1. 找到新增的产品，单击"产品"进入产品界面。
2. 在产品详情"基本信息"页面，单击"自定义模型"，配置产品的服务。
3. 新增服务类型"Connectivity"。 
   1. 在"添加服务"页面，填写"服务ID"、"服务类型"和"服务描述"，单击"确定"。
      - "服务ID"：Connectivity
      
      - "服务类型"：建议和服务ID保持一致
      
      - "服务描述"：Connectivity
        图4添加服务-Connectivity   
        ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001985112969.png "点击放大") 
       
   
   2. 在"Connectivity"的下拉菜单下单击"添加属性"，填写相关信息后，单击"确定"。
      - "属性名称"：dailyActivityTime
      
      - "数据类型"：int（整型）
      
      - "访问权限"：可读
      
      - "取值范围"：0\~65535
      
      - "步长"：1
      
      - "单位"：s
        图5新增属性-dailyActivityTime   
        ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001952154976.png "点击放大") 
       
   
   
   
   
4. 新增服务类型"Battery"。 
   1. 在"基本信息"下单击"添加服务"，填写"服务ID"、"服务类型"和"服务描述"，单击"确定"。
      - "服务ID"：Battery
      
      - "服务类型"：建议和服务ID保持一致
      
      - "服务描述"：Battery
        图6添加服务-Battery   
        ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001984996589.png "点击放大") 
       
   
   2. 在"Battery"的下拉菜单下单击"添加属性"，填写相关信息后，单击"确定"。
      - "属性名称"：batteryLevel
      
      - "数据类型"：int（整型）
      
      - "访问权限"：可读
      
      - "取值范围"：0-100
      
      - "步长"：1
      
      - "单位"：%
        图7新增属性-batteryLevel(Battery)   
        ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001985117617.png "点击放大") 
       
   
   
   
   
 
#### 上传设备CA证书
1. 在左侧导航栏选择"设备 \> 设备证书"，进入"设备CA证书"页签，选择资源空间，单击"上传证书"。
2. 在弹出的对话框中，单击"添加文件"，然后单击"确定"。 
   图8CA证书-上传证书   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981498265.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   - 设备CA证书由设备厂商提供，调测时可[自行制作调测证书]，商用时建议更换为商用证书，否则会带来安全风险。
   
   - CA 证书具有一个过期日期，在该日期后，这些证书将无法用于验证服务器的证书；请在 CA 证书的过期日期前替换这些证书，以确保设备可以正常的连接到IoT平台。
    
   
   
 
 #### 制作设备CA调测证书
本文以Windows环境为例，介绍通过Openssl工具制作调测证书的方法，生成的证书为PEM编码格式的证书。
1. 在浏览器中访问[这里](https://slproweb.com/products/Win32OpenSSL.html)，下载并进行安装OpenSSL工具。
2. 以管理员身份运行cmd命令行窗口。
3. 执行cd c:\\openssl\\bin（请替换为openssl实际安装路径），进入openssl命令视图。
4. 执行以下命令生成密钥对。
   ```
   openssl genrsa -out rootCA.key 2048
   ```
   
5. 执行以下命令，使用密钥对中的私有密钥生成 CA 证书。
   ```
   openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
   ```
   系统提示您输入如下信息，所有参数可以自定义。
   - Country Name (2 letter code) \[AU\]：国家，如CN。
     
   
   - State or Province Name (full name) \[\]: 省份，如GD。
     
   
   - Locality Name (for example, city) \[\]:城市，如SZ。
     
   
   - Organization Name (for example, company) \[\]：组织，如Huawei。
     
   
   - Organizational Unit Name (for example, section) \[\]：组织单位，如IoT。
     
   
   - Common Name (e.g. server FQDN or YOUR name) \[\]: 名称，如zhangsan。
     
   
   - Email Address \[\]:邮箱地址。
     
   
   
   在openssl安装目录的bin文件夹下，获取生成的CA证书（rootCA.pem）。
   
 
#### 上传验证证书
如果上传的是调测证书，上传后证书状态显示为"未验证"，您需要上传验证证书，来证明您拥有该CA证书。
图9CA证书-未验证证书   
![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981578397.png "点击放大")
验证证书是由设备CA证书对应的私钥创建的，请参考如下操作制作验证证书。
1. 获取验证证书的验证码
   
   图10CA证书-验证证书   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002480225392.png "点击放大")
   图11CA证书-获取验证码   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002480385984.png "点击放大")
   
   
2. 执行如下命令为私有密钥验证证书生成密钥对。 
   ```
   openssl genrsa -out verificationCert.key 2048
   ```
   
   
3. 执行如下命令为私有密钥验证证书创建CSR（Certificate Signing Request）。 
   ```
   openssl req -new -key verificationCert.key -out verificationCert.csr
   ```
   系统提示您输入如下信息，**Common Name填写为验证证书的验证码**，其他参数自定义。
   - Country Name (2 letter code) \[AU\]：国家，如CN。
     
   
   - State or Province Name (full name) \[\]: 省份，如GD。
     
   
   - Locality Name (for example, city) \[\]:城市，如SZ。
     
   
   - Organization Name (for example, company) \[\]：组织，如Huawei。
     
   
   - Organizational Unit Name (for example, section) \[\]：组织单位，如IoT。
     
   
   - Common Name (e.g. server FQDN or YOUR name) \[\]：验证证书的验证码，请参考[1]获取 。
     
   
   - Email Address \[\]:邮箱地址。
     
   
   - Password\[\]：密码。
   
   - Optional Company Name\[\]：公司名称，如Huawei。
   
   
   
   
4. 执行以下命令使用CSR创建私有密钥验证证书。 
   ```
   openssl x509 -req -in verificationCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out verificationCert.pem -days 500 -sha256
   ```
   在openssl安装目录的bin文件夹下，获取生成的验证证书（verificationCert.pem）。
   
   
5. 选择对应证书，单击![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001160619474.png)然后单击"上传验证证书"。
   
   图12CA证书-验证证书   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002480225392.png "点击放大")
   
   
6. 在弹出的对话框中，单击"添加文件"，然后单击"确定"。 
   图13CA证书-上传验证证书   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002480387530.png "点击放大")
   上传验证证书后，证书状态变为"已验证"，表明您拥有该CA证书。
   
   
#### 预置X.509证书
在注册X.509设备之前，您需要在设备侧预置CA机构签发的X.509证书。
![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
X.509证书由CA机构签发，若没有CA机构签发的商用证书，您可以自己[制作设备CA调测证书]。
**制作X.509调测证书**
1. 以管理员身份运行cmd命令行窗口，执行cd c:\\openssl\\bin（请替换为openssl实际安装路径），进入openssl命令视图。
2. 执行如下命令生成密钥对。
   ```
   openssl genrsa -out deviceCert.key 2048
   ```
   
3. 执行如下命令为设备证书创建CSR（Certificate Signing Request）。
   ```
   openssl req -new -key deviceCert.key -out deviceCert.csr
   ```
   系统提示您输入如下信息，所有参数可以自定义。
   - Country Name (2 letter code) \[AU\]：国家，如CN。
     
   
   - State or Province Name (full name) \[\]: 省份，如GD。
     
   
   - Locality Name (for example, city) \[\]:城市，如SZ。
     
   
   - Organization Name (for example, company) \[\]：组织，如Huawei。
     
   
   - Organizational Unit Name (for example, section) \[\]：组织单位，如IoT。
     
   
   - Common Name (e.g. server FQDN or YOUR name) \[\]: 名称，如zhangsan。
     
   
   - Email Address \[\]:邮箱地址。
     
   
   - Password\[\]：密码。
   
   - Optional Company Name\[\]：公司名称，如Huawei。
    
4. 执行以下命令使用CSR创建设备证书。
   ```
   openssl x509 -req -in deviceCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out deviceCert.pem -days 500 -sha256
   ```
   在openssl安装目录的bin文件夹下，获取生成的设备证书（deviceCert.pem）。
   
 #### 注册X.509证书认证的设备
1. 访问[设备接入服务](https://www.huaweicloud.com/product/iothub.html)，单击[管理控制台](https://console.huaweicloud.com/iotdm/#/dm-portal/home)进入设备接入控制台。
2. 在左侧导航栏选择" 设备 \> 所有设备"，单击"注册设备"，按照如下表格填写参数后，单击"确定"。 
   图14设备-注册X.509设备   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981327481.png "点击放大")
   
   | 参数名称      | 说明                                                                                                                                                                                                                                                                                              |
   |:---|:---|
   | 所属资源空间 | 选择设备所属的资源空间。                                                                                                                                                                                                                                                                                  |
   | 所属产品    | 选择设备所属的产品。 如没有，请先[创建产品]。                                                                                                                                                                   |
   | 设备标识码  | 即node_id，填写为设备的IMEI、MAC地址或Serial No；若没有真实设备，填写自定义字符串，由英文字母和数字组成                                                                                                                                                                                                                               |
   | 设备名称   | 即device_name，可自定义。                                                                                                                                                                                                                                                                              |
   | 设备认证类型    | X.509证书：设备使用X.509证书验证身份。                                                                                                                                                                                                                                                                        |
   | 指纹      | 当"设备认证类型"选择"X.509证书"时填写，导入[设备侧预置的设备证书]对应的指纹，在OpenSSL执行**openssl x509 -fingerprint -sha256 -in deviceCert.pe** **m** 命令可查询。**注：填写时需要删除冒号** 。![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001162540764.png "点击放大") |
      
   
   
 
#### 连接鉴权
参考[连接鉴权](https://support.huaweicloud.com/api-iothub/iot_06_v5_3009.html)接口文档，使用MQTT.fx工具激活在物联网平台上注册的设备。
1. 下载[MQTT.fx](https://iotda-document.obs.cn-north-4.myhuaweicloud.com/mqttfx-1.7.1-windows-x64.exe)（默认是64位操作系统，如果是32位操作系统，单击此处下载[MQTT.fx](https://iotda-document.obs.cn-north-4.myhuaweicloud.com/mqttfx-1.7.1-windows.exe)），安装MQTT.fx工具。
   
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   - 安装最新版MQTT.fx工具，可单击此处[下载](https://softblade.de/download/)。
   
   - MQTT.fx 1.7.0及旧版本对带有$的主题（Topic）处理存在问题，请使用最新版本进行测试。
    
   
   
2. 访问[这里](https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/)，填写[注册X.509证书认证的设备]后生成的设备ID（DeviceId）和密钥（DeviceSecret），生成连接信息（ClientId、Username、Password）。
   
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   DeviceSecret在此场景下可随意填写。
   图15获取ClientId   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001162478634.png "点击放大")
   
   | 参数       | 必选/可选 | 类型           | 参数描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   |:---|:---|:---|:---|
   | ClientId  | 必选     | String(256)   | 一机一密的设备clientId由4个部分组成：设备ID、设备身份标识类型、密码签名类型、时间戳，通过下划线"_"分隔。 - **设备ID**：指设备在平台成功注册后生成的唯一设备标识，通常由设备的产品ID和设备的NodeId通过分隔符"_"拼装而来。  - **设备身份标识类型**：固定值为0，表示设备ID。  - **密码签名类型** ：长度1字节，当前支持2种类型： - "0"代表HMACSHA256不校验时间戳。  - "1"代表HMACSHA256校验时间戳。    - **时间戳**：为设备连接平台时的UTC时间，格式为YYYYMMDDHH，如UTC 时间2018/7/24 17:56:20 则应表示为2018072417。   |
   | Username | 必选   | String(256) | 设备ID。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
      
   设备通过MQTT协议的connect消息进行鉴权，对于构造clientId的各个部分信息都必须包括进去，平台收到connect消息时，会判断设备的鉴权类型和密码摘要算法。
   使用生成工具生成的clientId格式，默认不校验时间戳：设备ID_0_0_时间戳。
   - 当采用"HMACSHA256"校验时间戳方式时，会先校验消息时间戳与平台时间是否一致，再判断密码是否正确。
   
   - 当采用"HMACSHA256"不校验时间戳方式时，鉴权消息也必须带时间戳，但不检验时间是否准确，仅判断密码是否正确。
   
   
   connect消息鉴权失败时，平台会返回错误，并自动断开MQTT链路。
   
   
3. 打开MQTT.fx软件，单击"设置"图标。 
   图16设置   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001207880107.png "点击放大")
   
   
4. 填写" Connection Profile" 相关信息。 
   图17"General "可以使用工具默认信息   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001211038845.png "点击放大")
   
   | 参数名称          | 说明                                                                                                                                                              |
   |:---|:---|
   | Broker Address | 填写从设备接入服务控制台获取的[设备对接地址]，此地址为域名信息。不能通过域名接入的设备，填写IP地址，详细请参考[2]中获取的。 |
   | Broker Port   | 为8883。                                                                                                                                                           |
   | Client ID     | 设备ClientID，请参考[2]中获取。                                                                                            |
      
   
   
5. 单击"User Credentials"填写"User Name"。 
   图18填写设备ID   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001165919146.png "点击放大")
   
   | 参数名称       | 说明                                                                 |
   |:---|:---|
   | User Name | 即设备ID，请参考[2]中获取。 |
   | Password  | 使用X.509证书认证时不需要填写。                                                |
      
   
   
6. 单击"SSL/TLS"配置鉴权参数，然后单击"Apply"。选择开启 "SSL/TLS"，勾选" Self signed certificates"，配置相关证书内容。 
   图19填写"SSL/TLS"相关参数   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001211162741.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   - CA File为对应的CA证书。下载并获取证书（加载pem格式的证书），获取证书请根据需要在[资源获取](https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section3)里下载。
   
   - Client Certificate File为设备的设备证书（deviceCert.pem）。
   
   - Client Key File为设备的私钥（deviceCert.key）。
    
   
   
7. 单击"Connect"，设备鉴权成功后，在物联网平台可以看到设备处于在线状态。 
   图20设备列表-设备在线   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001950367902.png "点击放大")
   
   
 
#### 上报数据
参考[设备属性上报](https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html)接口文档，使用MQTT.fx工具向物联网平台上报数据。
设备若通过MQTT通道上报数据，需要发给指定的topic，上报消息的topic格式为："$oc/devices/{device_id}/sys/properties/report"，其中"device_id"的值，为设备注册成功后返回的"device_id"值。
1. 填写数据上报的topic，此处以"$oc/devices/{device_id}/sys/properties/report"为例，如"$oc/devices/5e4e2e92ac-164aefa8fouquan1/sys/properties/report"。 
   图21填写接口地址   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001207998641.png "点击放大")
   
   
2. 填写上报的数据。 
   **请求参数**
   
   | 字段名      | 必选/可选 | 类型                            | 参数描述                                       |
   |:---|:---|:---|:---|
   | services | 必选       | List\<ServiceProperty\> | 设备服务数据列表（具体结构参考下表ServiceProperty定义表） |
      
   ServiceProperty定义表：
   
   | 字段名        | 必选/可选 | 类型      | 参数描述                                                                                                                                         |
   |:---|:---|:---|:---|
   | service_id | 必选       | String  | 设备服务的ID。                                                                                                                                    |
   | properties | 必选       | Object | 设备服务的属性列表，具体字段在设备关联的产品模型中定义。                                                                                                                 |
   | event_time | 可选         | String | 设备采集数据UTC时间（格式：yyyyMMddTHHmmssZ），如：20161219T114920Z。 设备上报数据不带该参数或参数格式错误时，则数据上报时间以平台时间为准。 |
      
   **请求示例**
   ```
   {
       "services": [{
               "service_id": "Connectivity",
               "properties": {
                   "dailyActivityTime": 57
               },
               "event_time": "20151212T121212Z"
           },
           {
               "service_id": "Battery",
               "properties": {
                   "batteryLevel": 80
               },
               "event_time": "20151212T121212Z"
           }
       ]
   }
   ```
   图22请求示例   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001207758631.png "点击放大")
   
   
3. 单击"Publish"，可以在物联网平台上查看设备是否成功上报数据。 
   图23查看上报属性-batteryLevel   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001985332805.png "点击放大")
   图24查看上报属性-batteryLevel   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001952253746.png "点击放大")
   
   
