

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

# SPEKE API v2 - 有关 DASH-IF 规范的自定义项和约束
<a name="speke-constraints-v2"></a>

DASH 行业论坛 [CPIX 2.3 规范](https://dashif.org/docs/CPIX2.3/Cpix.html)支持大量使用案例和拓扑。SPEKE API v2.0 规范定义了 CPIX 配置文件和 CPIX 的 API。为了实现这两个目标，它遵循 CPIX 规范，并具有以下自定义项和约束：

**CPIX 配置文件**
+ SPEKE 遵循 Encryptor Consumer 工作流。
+ 对于加密的内容密钥，SPEKE 应用以下限制：
  + SPEKE 不支持请求或响应负载的数字签名验证（XMLDSIG）。
  + SPEKE 需要基于 2048 位 RSA 的证书。
+ SPEKE 仅利用 CPIX 功能的子集：
  + SPEKE 会忽略 `UpdateHistoryItemList` 功能。如果响应中包含该列表，则 SPEKE 会将其忽略。
  + SPEKE 省略了 root/leaf 关键功能。如果响应中包含 `ContentKey@dependsOnKey` 属性，则 SPEKE 会将其忽略。
  + SPEKE 会忽略 `BitrateFilter` 元素和 `VideoFilter@wcg` 属性。如果这些元素或属性存在于 CPIX 负载中，SPEKE 会将其忽略。
+ 在与 SPEKE v2 交换的 CPIX 文档中，只能使用[标准负载组件页面](standard-payload-components-v2.md)或[加密合同页面](encryption-contract-v2.md)上提及“支持”的元素或属性。
+ 由加密程序包含在 CPIX 请求中时，所有元素和属性都应在密钥提供程序 CPIX 响应中带有有效值。否则，加密程序应停止并引发错误。
+ SPEKE 支持使用 `KeyPeriodFilter` 元素进行密钥轮换。SPEKE 仅使用 `ContentKeyPeriod@index` 来跟踪密钥周期。
+ 对于 HLS 信令，必须使用多个 `DRMSystem.HLSSignalingData` 元素：一个元素的 `DRMSystem.HLSSignalingData@playlist` 属性值为“media”，另一个元素的 `DRMSystem.HLSSignalingData@playlist` 属性值为“master”。
+ 当请求密钥时，加密程序可能会在 `ContentKey` 元素上使用可选的 `@explicitIV` 属性。密钥提供程序可以使用 `@explicitIV` 来响应 IV，即使该属性未包含在请求中。
+ 加密程序创建密钥标识符 (`KID`)，这对于任何给定的内容 ID 和密钥周期保持不变。密钥提供程序在其对请求文档的响应中包含 `KID`。
+ 加密程序应包含 `CPIX@contentId` 属性的值。当收到此属性的空值时，密钥提供程序应返回一条错误，相应描述为“缺少 CPIX@contentId”。`CPIX@contentId` 值不能被密钥提供程序覆盖。

   `CPIX@id` 值（如果不为空）应被密钥提供程序忽略。
+ 加密程序应包含 `CPIX@version` 属性的值。当收到此属性的空值时，密钥提供程序应返回一条错误，相应描述为“缺少 CPIX@version”。收到带有不支持版本的请求时，密钥提供程序返回的错误描述应为“不支持的 CPIX@version”。

   `CPIX@version` 值不能被密钥提供程序覆盖。
+ 加密程序应包括每个所请求密钥的 `ContentKey@commonEncryptionScheme` 属性值。当收到此属性的空值时，密钥提供者应返回一条错误消息，描述为 “缺少 ContentKey @ commonEncryptionScheme for KID`id`”。

  唯一的 CPIX 文档不能混合不同 `ContentKey@commonEncryptionScheme` 属性的多个值。收到此类组合时，密钥提供者应返回错误信息，并说明为 “不合规 ContentKey @ commonEncryptionScheme 组合”。

  并非所有 `ContentKey@commonEncryptionScheme` 值都与所有 DRM 技术兼容。当收到这样的组合时，密钥提供者应返回一个错误，描述为 “ContentKey@ commonEncryptionScheme 不兼容 DRMSystem `id`”。

   `ContentKey@commonEncryptionScheme` 值不能被密钥提供程序覆盖。
+ 在 CPIX 响应正文中接收到 `DRMSystem@PSSH` 和 `DRMSystem.ContentProtectionData` innerXML `<pssh>` 元素的不通知时，加密程序应停止并引发错误。

**CPIX 的 API**
+ 密钥提供程序应包含 `X-Speke-User-Agent` HTTP 响应标头的值。
+ 符合 SPEKE 的加密程序充当客户端并向密钥提供程序端点发送 POST 操作。
+ 加密器应包含 `X-Speke-Version` HTTP 请求标头的值，请求中使用的 SPEKE 版本，表述为。 MajorVersion MinorVersion，比如 SPEKE v2.0 的 “2.0”。如果密钥提供程序不支持加密程序在当前请求中使用的 SPEKE 版本，则密钥提供程序将返回错误，相应描述为“不支持的 SPEKE 版本”，并且不会尝试尽力处理 CPIX 文档。

  密钥提供程序无法在响应请求时修改加密程序定义的 `X-Speke-Version` 标头值。
+ 在响应正文中收到错误时，加密程序应引发错误，并且不会使用 SPEKE v1.0 版本控制重试请求。

  如果密钥提供程序没有返回错误，但未能返回包含强制信息的 CPIX 文档，则加密程序应停止并引发错误。

下表汇总了消息正文中密钥提供程序必须返回的标准消息。错误情况下的 HTTP 响应代码应为 4XX 或 5XX，绝不会是 200。422 错误代码可用于所有与 SPEKE/CPIX 相关的错误。


| 错误案例 | 错误消息 | 
| --- | --- | 
|  CPIX@contentId 未定义  |  缺少 CPIX@contentId  | 
|  CPIX@version 未定义  |  缺少 CPIX@version  | 
|  不支持 CPIX@version  |  不支持的 CPIX@version  | 
|  ContentKey@ commonEncryptionScheme 未定义  |  KID 缺少 ContentKey @ commonEncryptionScheme `id`（其中`id`等于 ContentKey @kid 值）  | 
|  在单个 CPIX 文档中使用多个 ContentKey @ commonEncryptionScheme 值  |  不合规 ContentKey @ commonEncryptionScheme 组合  | 
|  ContentKey@ commonEncryptionScheme 与 DRM 技术不兼容  |  ContentKey@ commonEncryptionScheme 不兼容 DRMSystem `id`（其中`id`等于 DRMSystem @systemId 值）  | 
|  X-Speke-Version 标头值不是支持的 SPEKE 版本  |  不支持的 SPEKE 版本  | 
|  加密合约格式不正确  |  格式不正确的加密合约  | 
|  加密合约与 DRM 安全级别约束相矛盾  |  不支持请求的 CPIX 加密合约  | 
|  加密合同不包含任何 VideoFilter 或 AudioFilter 元素  |  缺少 CPIX 加密合约  | 