Passa al contenuto principale

7. Certificate Management (证书管理) - Part 3

(续第7章 Part 2)

7.3.5. Account Key Rollover (账户密钥轮换)

客户端可能希望更改与账户关联的公钥, 以从密钥泄露中恢复或主动减轻未注意到的密钥泄露的影响。

要更改与账户关联的密钥, 客户端向服务器发送包含旧密钥和新密钥签名的请求。新密钥的签名涵盖账户 URL 和旧密钥, 表示新密钥持有者请求从旧密钥持有者接管账户。旧密钥的签名涵盖此请求及其签名, 并指示旧密钥持有者同意轮换请求。

要创建此请求对象, 客户端首先构造一个 keyChange 对象, 描述要更新的账户及其账户密钥:

account (必需, 字符串): 正在修改的账户的 URL。此字段的内容必须 (MUST) 是响应创建账户的 newAccount 请求的 Location 头字段中提供的确切字符串。

oldKey (必需, JWK): 旧密钥的 JWK 表示。

然后, 客户端将 keyChange 对象封装在 "内部" JWS 中, 使用请求的新账户密钥签名。此 "内部" JWS 成为 "外部" JWS 的有效载荷, 即 ACME 请求的主体。

外部 JWS 必须 (MUST) 满足 ACME JWS 请求主体的正常要求 (参见第 6.2 节)。内部 JWS 必须 (MUST) 满足正常要求, 但有以下差异:

  • 内部 JWS 必须 (MUST) 具有 "jwk" 头参数, 包含新密钥对的公钥。
  • 内部 JWS 必须 (MUST) 具有与外部 JWS 相同的 "url" 头参数。
  • 内部 JWS 必须 (MUST) 省略 "nonce" 头参数。

此事务具有来自旧密钥和新密钥的签名, 以便服务器可以验证两个密钥的持有者都同意更改。签名是嵌套的, 以保留 POST 消息上的所有签名都由一个密钥签名的属性。"内部" JWS 有效地表示新密钥持有者请求从旧密钥持有者接管账户的请求。"外部" JWS 表示当前账户持有者对此请求的同意。

POST /acme/key-change HTTP/1.1
Host: example.com
Content-Type: application/jose+json

{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "S9XaOcxP5McpnTcWPIhYuB",
"url": "https://example.com/acme/key-change"
}),
"payload": base64url({
"protected": base64url({
"alg": "ES256",
"jwk": /* new key */,
"url": "https://example.com/acme/key-change"
}),
"payload": base64url({
"account": "https://example.com/acme/acct/evOfKhNU60wg",
"oldKey": /* old key */
}),
"signature": "Xe8B94RD30Azj2ea...8BmZIRtcSKPSd8gU"
}),
"signature": "5TWiqIYQfIDfALQv...x9C2mg8JGPxl5bI4"
}

在接收到 keyChange 请求时, 除了典型的 JWS 验证外, 服务器必须 (MUST) 执行以下步骤:

  1. 验证 POST 请求属于当前活动的账户, 如第 6 节所述。

  2. 检查 JWS 的有效载荷是格式良好的 JWS 对象 ("内部 JWS")。

  3. 检查内部 JWS 的 JWS 保护头具有 "jwk" 字段。

  4. 检查内部 JWS 使用其 "jwk" 字段中的密钥进行验证。

  5. 检查内部 JWS 的有效载荷是格式良好的 keyChange 对象 (如上所述)。

  6. 检查内部和外部 JWS 的 "url" 参数相同。

  7. 检查 keyChange 对象的 "account" 字段包含与旧密钥匹配的账户的 URL (即, 外部 JWS 中的 "kid" 字段)。

  8. 检查 keyChange 对象的 "oldKey" 字段与所讨论账户的账户密钥相同。

  9. 检查不存在账户密钥与内部 JWS 的 "jwk" 头参数中的密钥相同的账户。

如果所有这些检查都通过, 则服务器通过用新公钥替换旧账户密钥来更新相应的账户, 并返回状态码 200 (OK)。否则, 服务器以错误状态码和描述错误的问题文档进行响应。如果存在具有提供的新密钥的现有账户, 则服务器应该 (SHOULD) 使用状态码 409 (Conflict) 并在 Location 头字段中提供该账户的 URL。

请注意, 更改账户的账户密钥不应该 (SHOULD NOT) 对账户产生任何其他影响。例如, 服务器禁止 (MUST NOT) 基于账户密钥的更改使待处理的订单或授权事务无效。

7.3.6. Account Deactivation (账户停用)

客户端可以通过向账户 URL 发布带有 "deactivated" 状态字段的签名更新来停用账户。当账户密钥被泄露或停用时, 客户端可能希望这样做。已停用的账户无法再请求证书颁发或访问与账户相关的资源, 例如订单或授权。如果服务器从已停用的账户接收 POST 或 POST-as-GET, 它必须 (MUST) 返回状态码 401 (Unauthorized) 和类型 "urn:ietf:params:acme:error:unauthorized" 的错误响应。

POST /acme/acct/evOfKhNU60wg HTTP/1.1
Host: example.com
Content-Type: application/jose+json

{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "ntuJWWSic4WVNSqeUmshgg",
"url": "https://example.com/acme/acct/evOfKhNU60wg"
}),
"payload": base64url({
"status": "deactivated"
}),
"signature": "earzVLd3m5M4xJzR...bVTqn7R08AKOVf3Y"
}

服务器必须 (MUST) 验证请求由账户密钥签名。如果服务器接受停用请求, 它会以状态码 200 (OK) 和账户对象的当前内容进行回复。

一旦账户被停用, 服务器禁止 (MUST NOT) 接受由该账户密钥授权的进一步请求。服务器应该 (SHOULD) 取消由账户密钥授权的任何待处理操作, 例如证书订单。服务器可以响应账户停用采取各种操作, 例如, 删除与该账户相关的数据或向账户的联系人发送邮件。服务器不应该 (SHOULD NOT) 吊销已停用账户颁发的证书, 因为这可能会导致使用这些证书的服务器的操作中断。ACME 不提供重新激活已停用账户的方法。

7.4. Applying for Certificate Issuance (申请证书颁发)

客户端通过向服务器的 newOrder 资源发送 POST 请求来开始证书颁发过程。POST 的主体是一个 JWS 对象, 其 JSON 有效载荷是第 7.1.3 节中定义的订单对象的子集, 包含描述要颁发的证书的字段:

identifiers (必需, 对象数组): 客户端希望为其提交订单的标识符对象数组。

  • type (必需, 字符串): 标识符的类型。

  • value (必需, 字符串): 标识符本身。

notBefore (可选, 字符串): 证书中 notBefore 字段的请求值, 采用 [RFC3339] 中定义的日期格式。

notAfter (可选, 字符串): 证书中 notAfter 字段的请求值, 采用 [RFC3339] 中定义的日期格式。

POST /acme/new-order HTTP/1.1
Host: example.com
Content-Type: application/jose+json

{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "5XJ1L3lEkMG7tR6pA00clA",
"url": "https://example.com/acme/new-order"
}),
"payload": base64url({
"identifiers": [
{ "type": "dns", "value": "www.example.org" },
{ "type": "dns", "value": "example.org" }
],
"notBefore": "2016-01-01T00:04:00+04:00",
"notAfter": "2016-01-08T00:04:00+04:00"
}),
"signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g"
}

如果服务器无法按指定完成请求, 它必须 (MUST) 返回错误, 并且禁止 (MUST NOT) 颁发内容与请求内容不同的证书。如果服务器要求以某种方式修改请求, 它应该使用适当的错误类型和描述来指示所需的更改。

如果服务器愿意颁发所请求的证书, 它会以 201 (Created) 响应进行回复。此响应的主体是反映客户端请求和客户端在颁发证书之前必须完成的任何授权的订单对象。

(继续7.4.1-7.6节...)