

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用证书提供程序进行自我管理的 AWS IoT Core 证书签名
<a name="provisioning-cert-provider"></a>

在 AWS IoT 队列配置中，您可以创建 AWS IoT Core 证书提供商来签署证书签名请求 (CSRs)。证书提供者引用 Lambda 函数以及[适用于实例集预调配的 `CreateCertificateFromCsr` MQTT API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr)。Lambda 函数接受 CSR 并返回签名的客户端证书。

当您的证书提供商没有证书提供商时 AWS 账户，系统会在队列配置中调用 [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 来从 CSR 生成证书。创建证书提供商后，[CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对此 MQTT API 的所有调用都将调用证书提供商来颁发证书。

借助 AWS IoT Core 证书提供商，您可以实施利用私有证书颁发机构 (CAs)（例如[AWS 私有 CA](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)其他公开信任 CAs的证书颁发机构）或您自己的公钥基础设施 (PKI) 来签署 CSR 的解决方案。此外，您还可以使用证书提供者来自定义客户端证书的字段，例如有效期、签名算法、颁发者和扩展等。

**重要**  
每个 AWS 账户只能创建一个证书提供者。签名行为更改适用于调用 [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的整个队列，直到您 AWS 账户从中删除证书提供商。

**Topics**
+ [自行管理的证书签名在实例集预调配中的工作原理](#provisioning-cert-provider-how-it-works)
+ [证书提供程者 Lambda 函数输入](#provisioning-cert-provider-lambda-input)
+ [证书提供者 Lambda 函数返回值](#provisioning-cert-provider-lambda-return)
+ [示例 Lambda 函数](#provisioning-cert-provider-lambda)
+ [实例集预调配的自行管理的证书签名](#provisioning-self-certificate-signing)
+ [AWS CLI 证书提供商的命令](#provisioning-cert-provider-cli)

## 自行管理的证书签名在实例集预调配中的工作原理
<a name="provisioning-cert-provider-how-it-works"></a>

### 重要概念
<a name="provisioning-cert-provider-concepts"></a>

以下概念提供的详细信息可以帮助您了解自管理证书签名在 AWS IoT 队列配置中的工作原理。有关更多信息，请参阅[使用实例集预调配来预调配没有设备证书的设备](https://docs.aws.amazon.com//iot/latest/developerguide/provision-wo-cert.html)。

**AWS IoT 舰队配置**  
使用 AWS IoT 队列配置（队列配置的缩写），可在设备首次连接时 AWS IoT Core 生成设备证书并将其安全地交付 AWS IoT Core 给您的设备。使用实例集预调配将没有设备证书的设备连接到 AWS IoT Core。

**证书签名请求（CSR）**。  
在队列配置过程中，设备 AWS IoT Core 通过[队列配置 MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html) 向发出请求。该请求包括证书签名请求（CSR），该请求将会得到签名以创建客户端证书。

**AWS 队列配置中的托管证书签名**  
AWS managed 是队列配置中证书签名的默认设置。使用 AWS 托管证书签名， AWS IoT Core 将 CSRs 使用自己的证书签名 CAs。

**实例集预调配中的自行管理的证书签名**  
自行管理是实例集预调配中的另一个证书签名选项。使用自我管理的证书签名，您可以创建 AWS IoT Core 证书提供商进行签名 CSRs。您可以使用自我管理的证书签名使用 AWS 私 CSRs 有 CA、其他公开信任的 CA 或您自己的公钥基础架构 (PKI) 生成的 CA 进行签名。

**AWS IoT Core 证书提供商**  
AWS IoT Core 证书提供商（证书提供者的缩写）是一种客户管理的资源，用于队列配置中的自我管理证书签名。

### 示意图
<a name="provisioning-cert-provider-diagram"></a>

下图简要说明了自证书签名在 AWS IoT 队列配置中的工作原理。

![\[AWS IoT Core 用于队列配置的证书提供商\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/provisioning-cert-provider.png)

+ 在制造新的物联网设备或将其引入设备队列时，它需要使用客户端证书进行身份验证 AWS IoT Core。
+ 作为队列配置过程的一部分，设备通过队列[配置 MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html) 向 AWS IoT Core 请求客户端证书。该请求包括证书签名请求（CSR）。
+ AWS IoT Core 调用证书提供者并将 CSR 作为输入传递给提供者。
+ 证书提供者将 CSR 作为输入并颁发客户端证书。

  对于 AWS 托管证书签名， AWS IoT Core 使用自己的 CA 对 CSR 进行签名并颁发客户端证书。
+ 有了颁发的客户端证书，设备将继续进行实例集预调配，并与 AWS IoT Core建立安全连接。

## 证书提供程者 Lambda 函数输入
<a name="provisioning-cert-provider-lambda-input"></a>

AWS IoT Core 当设备向 Lambda 函数注册时，会将以下对象发送到 Lambda 函数。`certificateSigningRequest` 的值是 `CreateCertificateFromCsr` 请求中提供的[隐私增强邮件（PEM）格式](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-format.html)的 CSR。`principalId`是发出`CreateCertificateFromCsr`请求 AWS IoT Core 时用于连接的主体的 ID。 `clientId`是为 MQTT 连接设置的客户端 ID。

```
{
	"certificateSigningRequest": "string",
	"principalId": "string",
	"clientId": "string"
}
```

## 证书提供者 Lambda 函数返回值
<a name="provisioning-cert-provider-lambda-return"></a>

Lambda 函数必须返回包含 `certificatePem` 值的响应。以下是成功响应的示例。 AWS IoT Core 将使用返回值 (`certificatePem`) 来创建证书。

```
{
	"certificatePem": "string"
}
```

如果注册成功，`CreateCertificateFromCsr` 将在 `CreateCertificateFromCsr` 响应中返回相同的 `certificatePem`。有关更多信息，请参阅的响应负载示例[CreateCertificateFromCsr](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr)。

## 示例 Lambda 函数
<a name="provisioning-cert-provider-lambda"></a>

在创建证书提供者之前，您必须创建 Lambda 函数来签署 CSR。以下是 Python 中的 Lambda 函数示例。此函数使用私有 CA 和 `SHA256WITHRSA` 签名算法调用 AWS 私有 CA 来对输入 CSR 进行签名。返回的客户证书的有效期为一年。有关私有 CA AWS 私有 CA 以及如何创建私有 CA 的更多信息，请参阅[什么是 AWS 私有 CA？](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html) 以及[创建私有 CA](https://docs.aws.amazon.com/privateca/latest/userguide/create-CA.html)。

```
import os
import time
import uuid
import boto3

def lambda_handler(event, context):
    ca_arn = os.environ['CA_ARN']
    csr = (event['certificateSigningRequest']).encode('utf-8')

    acmpca = boto3.client('acm-pca')
    cert_arn = acmpca.issue_certificate(
        CertificateAuthorityArn=ca_arn, 
        Csr=csr,
        Validity={"Type": "DAYS", "Value": 365}, 
        SigningAlgorithm='SHA256WITHRSA',
        IdempotencyToken=str(uuid.uuid4())
    )['CertificateArn']
    
    # Wait for certificate to be issued
    time.sleep(1)    
    cert_pem = acmpca.get_certificate(
        CertificateAuthorityArn=ca_arn,
        CertificateArn=cert_arn
    )['Certificate']
    
    return {
        'certificatePem': cert_pem
    }
```

**重要**  
Lambda 函数返回的证书必须具有与证书签名请求（CSR）相同的主题名称和公钥。
Lambda 函数必须在 5 秒钟内完成运行。
Lambda 函数必须与证书提供商 AWS 账户 资源位于同一区域中。
必须向 AWS IoT 服务委托人授予 Lambda 函数的调用权限。为避免[混淆代理问题](https://docs.aws.amazon.com//IAM/latest/UserGuide/confused-deputy.html)，我们建议您设置 `sourceArn` 和 `sourceAccount` 调用权限。有关更多信息，请参阅[防止跨服务混淆代理](https://docs.aws.amazon.com//iot/latest/developerguide/cross-service-confused-deputy-prevention.html)。

以下基于资源的 [Lambda](https://docs.aws.amazon.com//lambda/latest/dg/access-control-resource-based.html) 策略示例授予 AWS IoT 调用 Lambda 函数的权限：

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Id": "InvokePermission",
	"Statement": [
		{
			"Sid": "LambdaAllowIotProvider",
			"Effect": "Allow",
			"Principal": {
				"Service": "iot.amazonaws.com"
			},
			"Action": "lambda:InvokeFunction",
			"Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
			"Condition": {
				"StringEquals": {
					"AWS:SourceAccount": "123456789012"
				},
				"ArnLike": {
				"AWS:SourceArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider/my-certificate-provider"
				}
			}
		}
	]
}
```

## 实例集预调配的自行管理的证书签名
<a name="provisioning-self-certificate-signing"></a>

您可以使用 AWS CLI 或 AWS 管理控制台选择实例集预调配的自行管理的证书签名。

### AWS CLI
<a name="provisioning-self-certificate-signing-cli"></a>

要选择自我管理的证书签名，您必须创建 AWS IoT Core 证书提供商来 CSRs 登录队列配置。 AWS IoT Core 调用证书提供程序，该提供程序将 CSR 作为输入并返回客户端证书。要创建证书提供者，请使用 `CreateCertificateProvider` API 操作或 `create-certificate-provider` CLI 命令。

**注意**  
创建证书提供者后，[适用于实例集预置的 `CreateCertificateFromCsr` API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对 `CreateCertificateFromCsr` 的所有调用都将调用证书提供者来颁发证书。在创建证书提供程者后，此行为可能需要几分钟才会发生变化。

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)`。

### AWS 管理控制台
<a name="provisioning-self-certificate-signing-console"></a>

要选择使用自行管理的证书签名 AWS 管理控制台，请执行以下步骤：

1. 转到 [AWS IoT 控制台](https://console.aws.amazon.com//iot/home)。

1. 在左侧导航栏中的**安全性**下，选择**证书签名**。

1. 在**证书签名**页面的**证书签名详细信息**下，选择**编辑证书签名方法**。

1. 在**编辑证书签名方法**页面的**证书签名方法**下，选择**自行管理**。

1. 在**自行管理设置**部分，输入证书提供者的名称，然后创建或选择 Lambda 函数。

1. 选择**更新证书签名**。

## AWS CLI 证书提供商的命令
<a name="provisioning-cert-provider-cli"></a>

### 创建证书提供者
<a name="provisioning-create-cert-provider"></a>

要创建证书提供者，请使用 `CreateCertificateProvider` API 操作或 `create-certificate-provider` CLI 命令。

**注意**  
创建证书提供者后，[适用于实例集预置的 `CreateCertificateFromCsr` API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对 `CreateCertificateFromCsr` 的所有调用都将调用证书提供者来颁发证书。在创建证书提供程者后，此行为可能需要几分钟才会发生变化。

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)`。

### 更新证书提供者
<a name="provisioning-update-cert-provider"></a>

要更新证书提供者，请使用 `UpdateCertificateProvider` API 操作或 `update-certificate-provider` CLI 命令。

```
aws iot update-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-2 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[UpdateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_UpdateCertificateProvider.html)`。

### 描述证书提供者
<a name="provisioning-describe-cert-provider"></a>

要描述证书提供者，请使用 `DescribeCertificateProvider` API 操作或 `describe-certificate-provider` CLI 命令。

```
aws iot describe-certificate-provider --certificateProviderName my-certificate-provider
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"lambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
	"accountDefaultForOperations": [
		"CreateCertificateFromCsr"
	],
	"creationDate": "2022-11-03T00:15",
	"lastModifiedDate": "2022-11-18T00:15"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[DescribeCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DescribeCertificateProvider.html)`。

### 删除证书提供者
<a name="provisioning-delete-cert-provider"></a>

要删除证书提供者，请使用 `DeleteCertificateProvider` API 操作或 `delete-certificate-provider` CLI 命令。如果您删除证书提供商资源，则的行为`CreateCertificateFromCsr`将恢复， AWS IoT 并将创建 AWS IoT 由 CSR 签名的证书。

```
aws iot delete-certificate-provider --certificateProviderName my-certificate-provider
```

此命令不会生成任何输出。

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[DeleteCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DeleteCertificateProvider.html)`。

### 列出证书提供者
<a name="provisioning-list-cert-provider"></a>

要列出您的证书提供商 AWS 账户，请使用 `ListCertificateProviders` API 操作或 `list-certificate-providers` CLI 命令。

```
aws iot list-certificate-providers
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviders": [
		{
			"certificateProviderName": "my-certificate-provider",
			"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
		}
	]
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 [https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html](https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html)。