亚马逊AWS官方博客

使用 AWS PCA 构建符合 Matter 要求的 IoT 证书体系

概述

构建 IoT 产品时,我们的证书体系构建一直是一个比较重要的一环,证书的发布,管理是否合规,都会对业务产生巨大的影响,而且 Matter 协议也对 IoT 设备的证书体系提出了要求。

Matter 协议是 CSA(Connectivity Standards Alliance)连接标准联盟于 2021 年推出的应用层连接协议,也是一个关注安全与隐私的互联协议,采用了密码学机制,能够确保安全地实现(参考 1):

  • 受信设备
  • 受信控制器
  • 隐私通讯

在 Matter 协议中,采用基于公钥基础设施(PKI)的安全模型,这是一种使用非常广泛的安全模型,比如我们常见的 https 请求中,就采用了该模型。PKI 可以帮助我们实现核实身份&保证数据的隐私性和完整性的安全需求。在 AWS 中,AWS Private Certificate Authority(AWS Private CA,以下简称 PCA)就是一个满足 PKI 需求的服务。

2023 年 1 月 3 号,AWS 也发布了 PCA 可以帮助通过 Matter 认证的说明(参考2),使用 PCA 来构建 IoT 设备的证书体系可以帮助我们更加简单快速的通过 CSA 认证。

Matter 协议中,PAA、PAI、DAC 是 commissionee 所必备的,以下是相关说明:

  • PAA:产品认证根证书
  • PAI:产品认证中间证书
  • DAC:设备认证证书 ,设备与 commissioner 认证时使用证书,因为其是 X509 证书,设备与 IoT Core 建立连接时,也可以使用该证书与云端进行身份校验

这里使用一张图片梳理下对于 Matter 协议所需的证书间的关系:

以下,我们就会说明如何使用 PCA 来生成 PAA,PAI 与 DAC, 并将其注册到 AWS IoT Core 的 CA 注册中心中,并用其签发证书,结合到我们的 IoT 业务中。

使用 AWS Private CA 生成 PAA,PAI

申请 AWS PrivateCA CA 证书(注意,PCA 有一定成本,具体参考:https://aws.amazon.com/cn/private-ca/pricing/

所有代码均来自 AWS 官方文档:https://docs.aws.amazon.com/privateca/latest/userguide/API-CBR-intro.html

注意,生成 PAA 时,注意依赖与使用参数,作者编译运行的完整代码地址为:https://github.com/ThinSnorlax/MatterCABuild

在运行代码前,需要在本地配置 AWS credentials 文件,windows 操作系统中,一般位于 C:\Users\name.aws\credentials; Linux 操作系统中,位于~/.aws/credentials。方便起见,建议使用 AWS 命令行工具,用 AWS configure 命令自动生成。

AWS CLI 安装文档:https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html 注意,配置时,使用的访问密钥皆来自于 IAM User。

PAA 生成

运行 ProductAttestationAuthorityActivation 类,注意,替换 endpointRegion 参数,并记录生成的 CA ARN。

生成后,PCA 控制台中可以查询到该 CA:

PAI 生成

运行 ProductAttestationIntermediateActivation 类,注意以下配置项:

a) 参数 PAA Arn 需要替换为我们生成的 PAA 的 arn,可以在 AWS PCA Console 中对应 CA 的详情中寻找,也可以看 ProductAttestationAuthorityActivation 类执行时的输出;
b) 同理,我们需要替换 region 参数;
c) 代码 83 行指定的 1.3.6.1.4.1.37244.2.1,为 VID,生产需要自行替换 84 行的值,VID 由 CSA 提供;
d) 代码 84 行指定的 1.3.6.1.4.1.37244.2.1,为 PID,生产需要自行替换 87 行的值。

生成后,控制台中可以查询到该PAI:

使用 PAI 创建 DAC

  • openssl 生成 csr 文件和证书密钥 key 文件,参考命令如下:
openssl ecparam -out elsenow-ecc.key -name prime256v1 -genkey
openssl req -nodes -new -key elsenow-ecc.key \
            -out matter-registration.csr \
cat iot-registration.csr

记录下 cat matter-registration.csr 输出的结果,并替换 IssueDeviceAttestationCertificate 类中代码第 94 行的 strCSR 参数的值,替换后如下:

替换代码 76 行 region 参数,endpointRegion。

替换代码 91 行 PAI 的 ARN,PAI ARN 在生成时会打印,也可以在 ACM PCA 控制台查询。

执行代码后,会打印 DAC 的 ARN。

  • 等待证书发布完成:
aws acm-pca wait certificate-issued \
    --certificate-authority-arn [替换为您自己的 PAI ARN] \
    --certificate-arn [替换为您自己的证书 ARN]
  • 获取证书内容:
aws acm-pca get-certificate \
    --certificate-authority-arn [替换为您自己的 PAI ARN] \
    --certificate-arn [替换为您自己的证书 ARN]

导入 CA 至 AWS IoT Core CA

注意,AWS IoT Core 中的 CA 中心,导入需要使用验证证书 +CA 证书的形式,对 CA 证书拥有权进行校验,才可以导入 CA 中心,因此,我们在 IoT Core 中添加 CA 前,需要先使用 AWS PCA-API+Openssl 工具生成校验证书,注意,我们这里使用 PAI 生成验证证书。

  • 获取 PCA 的证书,并导入本地文件,可以使用 AWS CLI 命令,命令如下:
aws acm-pca get-certificate-authority-certificate \
    --certificate-authority-arn 【替换您自己的 PAI ARN】
    --output text > acm-pca-pai-ca.pem
  • 使用 openssl 验证是否一致:
openssl x509 -text -noout -in acm-pca-pai-ca.pem 

此命令会输出证书信息,可以对比控制台上的 PCA 信息,确认证书是否正确。

  • AWS IoT Core CA 中心注册码,可以在控制台使用创建 CA 时查询, 也可以用如下 CLI 命令获取:
aws iot get-registration-code --output text
  • openssl 生成 csr 文件和证书密钥 key 文件,参考命令如下,注意 registration-code 为上一步输出结果:
openssl req -nodes -new -key elsenow-ecc.key \
            -out iot-registration.csr \
            -subj "/CN=[替换您自己的 registration-code]"

注意,本命令会在当前文件夹生成 iot-registration.csr 文件。

  • acm-pca 的 issue-certificate API 发布证书,注意当前 PCA 与 ACM 控制台没有该 API 入口,控制台中,证书管理处的请求证书按钮为 acm 的 request-certificate API,两者不一致,请勿搞混,参考命令如下:
aws acm-pca issue-certificate \
    --certificate-authority-arn [替换为您自己的 CA ARN] \
    --csr file://./iot-registration.csr \
    --signing-algorithm "SHA256WITHECDSA" \
    --validity Value=1,Type="DAYS" \
    --idempotency-token $(date +'%Y%m%d%H%M%S')

API 调用成功后,会输出证书 ARN,请记录证书 ARN

注意,如果使用 CLI 2.9 版本可能会遇到 CA 正则不匹配错误,可以参考以下 python 代码,使用代码发布:

import boto3
import time

client = boto3.client('acm-pca')
ca_arn = '替换您自己的 ca arn'
csr_path = './iot-registration.csr'   #csr 文件路径,根据需要替换


def issue_certificate():
    cert = open(csr_path, 'rb').read()
    print(cert)
    print(type(cert))
    response = client.issue_certificate(
        CertificateAuthorityArn=ca_arn,
        Csr=cert,
        SigningAlgorithm='SHA256WITHECDSA',
        Validity={
            'Value': 1,
            'Type': 'DAYS'
        },
        IdempotencyToken=str(time.time())
    )
    print(response)


if __name__ == '__main__':
    issue_certificate()
  • 等待证书发布完成:
aws acm-pca wait certificate-issued \
    --certificate-authority-arn [替换为您自己的 CA ARN] \
    --certificate-arn [替换为您自己的证书 ARN]
  • 获取证书内容:
aws acm-pca get-certificate \
    --certificate-authority-arn [替换为您自己的 CA ARN] \
    --certificate-arn [替换为您自己的证书 ARN] > iot-registration.json
  • 命令或者手动将第三步输出结果的 json 中,Certificate 字段内容保存至 iot-registration.crt 文件中,生成的 iot-registration.crt 文件为我们的 CA 注册时使用的验证文件:
jq -r '.Certificate' iot-registration.json > iot-registration.crt
  • 验证该文件的 CN 是否为 iot registration-code:
openssl x509 -text -noout -in iot-registration.crt -subject

输出如下:

subject= /CN=[您的 registration-code]

也可以使用 AWS CLI,参考命令如下:

aws iot register-ca-certificate \
    --allow-auto-registration \
    --set-as-active \
    --ca-certificate file://./acm-pca-pai-ca.pem \
    --verification-cert file://./iot-registration.crt

至此,我们完成了 IoT Core 中 CA 注册中心的创建, 且开启了 CA 的自动注册属性。

使用 PCA 发布证书并连接到 AWS IoT Core

使用 acm-pca 发布一个证书,用来与 IoT Core 进行通讯;

  • 使用 Openssl 生成证书密钥和 csr 文件,subj 可以替换为您的信息:
openssl req -nodes -new -key elsenow-ecc.key \
            -out deviceCert.csr \
            -subj "/C=CN/CN=snx-test-device"
  • 发布证书,同上,我们需要调用 issue-certificate 和等待证书发布完成,参考命令如下,如果遇到 csr 正则校验不通过错误,参考上述 python 代码:
aws acm-pca issue-certificate \
    —certificate-authority-arn [替换您自己的CA ARN] \
    --csr file://./deviceCert.csr \
    —signing-algorithm "SHA256WITHECDSA" \
    —validity Value=365,Type="DAYS" \
    —idempotency-token $(date +'%Y%m%d%H%M%S')
aws acm-pca wait certificate-issued \
    --certificate-authority-arn [替换为您自己的PCA中PAI ARN] \
    --certificate-arn [替换为第一步中输出的证书ARN]
  • 同样,我们需要获取证书内容:
aws acm-pca get-certificate \
    --certificate-authority-arn [替换为您自己的PCA ARN] \
    --certificate-arn [替换为第一步中输出的证书ARN] > deviceCert.json
  • 然后,相对于生成验证证书,我们发布设备证书时,除了需要获取证书正文保存到证书文件中,还需要将 CA 证书+设备证书保存到证书链文件中,用于自动注册证书(注意,需要 CA 开启自动证书注册属性,如果没有开启,可以不需要证书链,并手动注册证书),参考命令如下:
# 生成证书文件
jq -r '.Certificate' deviceCert.json > deviceCert.crt
# 生成证书链文件
jq -r '.Certificate' deviceCert.json > deviceCertAndCACert.crt
cat acm-pca-pai-ca.pem >> deviceCertAndCACert.crt

注意,acm-pca-pai-ca.pem 的格式,需要对齐,建议执行前先检查一次,以下是正确示例:

  • 至此,我们已经完成了所有证书申请的步骤,我们可以开始来进行测试连接,此次连接使用证书为包含 CA 证书的证书链证书,用来进行初始化连接,我们可以使用 mosquitto_pub 工具进行测试连接,各位也可以选择使用自己常用的 MQTT 连接工具:
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem  
mosquitto_pub --cafile ./AmazonRootCA1.pem \
  --cert deviceCertAndCACert.crt \
  --key elsenow-ecc.key  \
  -h 您的IOT_ENDPOINT -p 8883 -q 1 -t  cmd/my-device/welcome -i test-thing \
  --tls-version tlsv1.2 -m '{"lalala": "test"}' -d

注意,本次连接肯定失败,输出结果如下(红字部分为您的设备名称):
Client my-device sending CONNECT
Error: The connection was lost.

  • 初次连接失败后,我们就可以去控制台检查是否有证书生成:

  • 有证书之后,我们就可以绑定策略与 IoT Thing,执行以下命令,激活证书,创建策略,并与我们自动生成的证书关联接,创建 IoT 物品,并与证书关联(这几个步骤,AWS 提供了 JITP 等方式实现自动注册,本实验主要为了解设备证书注册与激活流程,没有设置 JITP 流程,在生产中,建议使用 JITP 流程,参考 3)
aws iot update-certificate \
    --certificate-id [替换您自己的证书 ID] \
    --new-status ACTIVE
cat > policy.json << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:*"
            ],
            "Resource": "*"
        }
    ]
}
EOF
aws iot create-policy \
    --policy-name test \
    --policy-document file://./policy.json
aws iot attach-policy \
    --policy-name test \
    --target [替换您自己的证书 arn]
aws iot create-thing --thing-name test-thing
aws iot attach-thing-principal \
    --thing-name test-thing \
    --principal 【替换您自己的证书 arn】
  • 然后,我们就可以使用设备证书来进行 MQTT 连接,参考命令如下:
mosquitto_pub --cafile ./AmazonRootCA1.pem \
  --cert deviceCert.crt \
  --key elsenow-ecc.key  \
  -h 您的IOT_ENDPOINT -p 8883 -q 1 -t  dt/my-device/welcome -i test-thing \
  --tls-version tlsv1.2 -m '{"i am": "test success"}' -d

成功输出如下:

Client my-device sending CONNECT
Client my-device received CONNACK (0)
Client my-device sending PUBLISH (d0, q1, r0, m1, 'dt/my-device/welcome', ... (35 bytes))
Client my-device received PUBACK (Mid: 1, RC:0)

结束语

使用 PCA 生成的 CA 构建我们 IoT 设备的证书体系,可以保证整个证书的发布流程都是符合 Matter 协议要求,并完成 IoT 设备的初始化流程。

在整个 PAA,PAI,DAC 创建过程中,我们有用到 Matter 里面定义的 VID,PID 等参数,对该类参数的说明,可以参考如下表格:

参考

本篇作者

郑辉

亚马逊云科技解决方案架构师,负责基于亚马逊云计算方案架构的咨询和设计,在国内推广亚马逊云平台技术和各种解决方案。同时负责物联网行业解决方案开发和推广,在物联网,移动端开发等领域有着广泛的设计和实践经验。

王旭东

亚马逊云科技安全产品解决方案架构师,负责帮助客户进行安全解决方案的架构设计。在加入亚马逊云科技之前,曾在互联网 SaaS 企业负责公司基础架构安全建设及治理。

徐开

AWS 物联网实验室解决方案架构师,主要负责物联网解决方案,致力于 AWS IoT 相关技术的的推广与应用。