

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

# AWS Encryption SDK 消息格式参考
<a name="message-format"></a>


|  | 
| --- |
|  本页面提供了在您构建与 AWS Encryption SDK兼容的加密库时可供参考的信息。如果您不需要构建自己的兼容加密库，则可能不需要此信息。 要 AWS Encryption SDK 在支持的编程语言之一中使用，请参阅[编程语言](programming-languages.md)。 有关定义适当 AWS Encryption SDK 实现要素的规范，请参阅中的[AWS Encryption SDK 规范](https://github.com/awslabs/aws-encryption-sdk-specification/) GitHub。  | 

中的加密操作 AWS Encryption SDK 返回包含加密数据（密文）和所有加密数据密钥的单个数据结构或加密[消息](concepts.md#message)。要了解该数据结构或构建读取和写入该结构的库，您需要了解消息格式。

消息格式包含至少两个部分：*标头* 和*正文*。在某些情况下，消息格式包含第三个部分（*脚注*）。消息格式按网络字节顺序定义有序的字节序列，也称为 big-endian 格式。消息格式从标头开始，然后是正文，最后是脚注（如果有）。

 AWS Encryption SDK 支持的[算法套件](algorithms-reference.md)使用两种消息格式版本之一。没有[密钥承诺](concepts.md#key-commitment)的算法套件使用消息格式版本 1。带有密钥承诺的算法套件使用消息格式版本 2。

**Topics**
+ [标头结构](#header-structure)
+ [正文结构](#body-structure)
+ [脚注结构](#footer-structure)

## 标头结构
<a name="header-structure"></a>

消息标头包含加密的数据密钥以及有关消息正文组成方式的消息。下表描述了在消息格式版本 1 和版本 2 中构成标头的字段。字节是按显示的顺序附加的。

**不存在**值表示该字段在该版本的消息格式中不存在。**粗体文本**表示每个版本中不同的值。

**注意**  
您可能需要水平或垂直滚动才能查看此表中的所有数据。


**标头结构**  

| 字段 | 消息格式版本 1长度（字节） | 消息格式版本 2长度（字节） | 
| --- | --- | --- | 
| [Version](#header-version) | 1 | 1 | 
| [Type](#header-type) | 1 | 不存在 | 
| [Algorithm ID](#header-algorithm-id) | 2 | 2 | 
| [Message ID](#header-message-id) | 16 | 32 | 
| [AAD Length](#header-aad-length) | 2如果[加密上下文](concepts.md#encryption-context)为空，则 2 字节 AAD 长度字段的值为 0。 | 2如果[加密上下文](concepts.md#encryption-context)为空，则 2 字节 AAD 长度字段的值为 0。 | 
| [AAD](#header-aad) | 变量。此字段的长度显示在前 2 个字节中（AAD 长度字段）。 如果[加密上下文](concepts.md#encryption-context)为空，则在标头中不包含 AAD 字段。 |  变量。此字段的长度显示在前 2 个字节中（AAD 长度字段）。 如果[加密上下文](concepts.md#encryption-context)为空，则在标头中不包含 AAD 字段。  | 
| [Encrypted Data Key Count](#header-data-key-count) | 2 | 2 | 
| [Encrypted Data Key(s)](#header-data-keys) | 变量。由加密的数据密钥数和每个密钥的长度决定。 | 变量。由加密的数据密钥数和每个密钥的长度决定。 | 
| [Content Type](#header-content-type) | 1 | 1 | 
| [Reserved](#header-reserved) | 4 | 不存在 | 
| [IV Length](#header-iv-length) | 1 | 不存在 | 
| [Frame Length](#header-frame-length) | 4 | 4 | 
| [Algorithm Suite Data](#algorithm-suite-data) | 不存在 | 变量。由生成消息的[算法](algorithms-reference.md)决定。 | 
| [Header Authentication](#header-authentication) | 变量。由生成消息的[算法](algorithms-reference.md)决定。 | 变量。由生成消息的[算法](algorithms-reference.md)决定。 | 

**版本**  
该消息格式的版本。版本为 1 或 2，在十六进制表示法中编码为字节 `01` 或 `02`

**类型**  
该消息格式的类型。该类型指示结构的种类。唯一支持的类型描述为*客户验证的加密数据*。其类型值为 128，在十六进制表示法中编码为字节 `80`。  
此字段在消息格式版本 2 中不存在。

**算法 ID**  
使用的算法的标识符。这是一个解释为 16 位无符号整数的 2 字节值。有关算法的更多信息，请参阅[AWS Encryption SDK 算法参考](algorithms-reference.md)。

**消息 ID**  
随机生成的值，用于标识消息。消息 ID：  
+ 唯一地标识加密的消息。
+ 将消息标头弱绑定到消息正文。
+ 提供一种机制以安全地在多个加密的消息中重用数据密钥。
+ 防止在 AWS Encryption SDK中意外重复使用数据密钥或导致密钥失效。
此值在消息格式版本 1 中为 128 位，在版本 2 中为 256 位。

**AAD 长度**  
其他经过身份验证的数据 (AAD) 的长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含 AAD 的字节数。  
如果[加密上下文](concepts.md#encryption-context)为空，则 AAD 长度字段的值为 0。

**AAD**  
其他经过身份验证的数据。AAD 是编码形式的[加密上下文](concepts.md#encryption-context)，这是一个键值对数组，其中，每个键和值是一个 UTF-8 编码的字符串。加密上下文将转换为一个字节序列并用于 AAD 值。如果加密上下文为空，则在标头中不包含 AAD 字段。  
在使用[具有签名的算法](algorithms-reference.md)时，加密上下文必须包含 `{'aws-crypto-public-key', Qtxt}` 键值对。Qtxt 表示根据 [SEC 1 2.0 版](http://www.secg.org/sec1-v2.pdf)压缩并进行 Base64 编码的椭圆曲线点 Q。加密上下文可以包含额外的值，但构造的 AAD 的最大长度为 2^16 - 1 字节。  
下表描述了组成 AAD 的字段。键值对是根据 UTF-8 字符代码按键升序排列的。字节是按显示的顺序附加的。    
**AAD 结构**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/message-format.html)  
**键值对计数**  
AAD 中的键值对数。这是一个解释为 16 位无符号整数的 2 字节值，它指定 AAD 中的键值对数。AAD 中的最大键值对数为 2^16 - 1 个。  
如果没有加密上下文或加密上下文为空，则在 AAD 结构中不包含该字段。  
**密钥长度**  
键值对的键长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含键的字节数。  
**钥匙**  
键值对的键。这是 UTF-8 编码的字节序列。  
**值长度**  
键值对的值长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含值的字节数。  
**价值**  
键值对的值。这是 UTF-8 编码的字节序列。

**加密数据密钥计数**  
加密的数据密钥数。这是一个解释为 16 位无符号整数的 2 字节值，它指定加密的数据密钥数。每条消息中加密数据密钥的最大数量为 65535（2^16 - 1）。

**加密的数据密钥**  
加密的数据密钥序列。序列长度由加密的数据密钥数和每个密钥的长度决定。该序列包含至少一个加密的数据密钥。  
下表描述了组成每个加密的数据密钥的字段。字节是按显示的顺序附加的。    
**加密的数据密钥结构**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/message-format.html)  
**密钥提供商 ID 长度**  
密钥提供程序标识符的长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含密钥提供程序 ID 的字节数。  
**密钥提供商 ID**  
密钥提供程序标识符。它用于指示加密的数据密钥的提供程序，并且可以进行扩展。  
**密钥提供者信息长度**  
密钥提供程序信息的长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含密钥提供程序信息的字节数。  
**密钥提供商信息**  
密钥提供程序信息。这是由密钥提供程序决定的。  
当 AWS KMS 是主密钥提供者或者您正在使用密 AWS KMS 钥环时，此值包含的 Amazon 资源名称 (ARN)。 AWS KMS key  
**加密数据密钥长度**  
加密的数据密钥的长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含加密的数据密钥的字节数。  
**加密的数据密钥**  
加密的数据密钥。这是密钥提供程序加密的数据加密密钥。

**内容类型**  
加密数据的类型（非帧或帧）。  
尽可能使用帧数据。仅 AWS Encryption SDK 支持传统使用的非成帧数据。的某些语言实现仍然 AWS Encryption SDK 可以生成非成帧的密文。所有支持的语言实现都可以解密成帧和非帧加密文字。
帧数据分割成一些等长的部分；每个部分是单独加密的。帧内容为类型 2，在十六进制表示法中编码为字节 `02`。  
非帧数据不会被分割；是单一的加密 Blob。非帧内容为类型 1，在十六进制表示法中编码为字节 `01`。

**已保留**  
预留的 4 字节序列。该值必须为 0。它在十六进制表示法中编码为字节 `00 00 00 00`（即，等于 0 的 32 位整数值的 4 字节序列）。  
此字段在消息格式版本 2 中不存在。

**四、长度**  
初始化向量 (IV) 的长度。这是一个解释为 8 位无符号整数的 1 字节值，它指定包含 IV 的字节数。该值由生成消息的[算法](algorithms-reference.md)的 IV 字节值决定。  
此字段在消息格式版本 2 中不存在，该版本仅支持在消息标头中使用确定性 IV 值的算法套件。

**帧长**  
帧数据的每个帧的长度。这是一个解释为 32 位无符号整数的 4 字节值，该值指定每个帧的字节数。当数据为非帧数据时，也就是说，当 `Content Type` 字段的值为 1 时，该值必须为 0。  
尽可能使用帧数据。仅 AWS Encryption SDK 支持传统使用的非成帧数据。的某些语言实现仍然 AWS Encryption SDK 可以生成非成帧的密文。所有支持的语言实现都可以解密成帧和非帧加密文字。

**算法套件数据**  
生成消息的[算法](algorithms-reference.md)所需的补充数据。长度和内容由算法决定。其长度可能是 0。  
此字段在消息格式版本 1 中不存在。

**标头认证**  
标头身份验证是由生成消息的[算法](algorithms-reference.md)决定的。标头身份验证是在整个标头上计算的。它包含 IV 和身份验证标签。字节是按显示的顺序附加的。    
**标头身份验证结构**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/message-format.html)  
**四**  
用于计算标头身份验证标签的初始化向量 (IV)。  
此字段在消息格式版本 2 的标头中不存在。消息格式版本 2 仅支持在消息标头中使用确定性 IV 值的算法套件。  
**身份验证标签**  
标头的身份验证值。它用于对全部标头内容进行身份验证。

## 正文结构
<a name="body-structure"></a>

消息正文包含加密的数据（称为*密文*）。正文结构取决于内容类型（非帧或帧）。以下几节介绍了每种内容类型的消息正文格式。消息格式版本 1 和 2 中的消息正文结构相同。

**Topics**
+ [非帧数据](#body-no-framing)
+ [帧数据](#body-framing)

### 非帧数据
<a name="body-no-framing"></a>

非帧数据是在具有唯一 IV 和[正文 AAD](body-aad-reference.md) 的单个 blob 中加密的。

**注意**  
尽可能使用帧数据。仅 AWS Encryption SDK 支持传统使用的非成帧数据。的某些语言实现仍然 AWS Encryption SDK 可以生成非成帧的密文。所有支持的语言实现都可以解密成帧和非帧加密文字。

下表描述了组成非帧数据的字段。字节是按显示的顺序附加的。


**非帧正文结构**  

| 字段 | 长度（字节） | 
| --- | --- | 
| [IV](#body-unframed-iv) | 变量。等于在标头的 [IV Length](#header-iv-length) 字节中指定的值。 | 
| [Encrypted Content Length](#body-unframed-content-length) | 8 | 
| [Encrypted Content](#body-unframed-content) | 变量。等于在前 8 个字节（加密的内容长度）中指定的值。 | 
| [Authentication Tag](#body-unframed-tag) | 变量。由使用的[算法实施](algorithms-reference.md)决定。 | 

**四**  
与[加密算法](algorithms-reference.md)一起使用的初始化向量 (IV)。

**加密内容长度**  
加密的内容（或*密文*）的长度。这是一个解释为 64 位无符号整数的 8 字节值，它指定包含加密的内容的字节数。  
从技术上讲，允许的最大值为 2^63 - 1 或 8 艾字节 (8 EiB)。但实际上，由于[实施的算法](algorithms-reference.md)施加的限制，最大值为 2^36 - 32 或 64 吉字节 (64 GiB)。  
由于 Java 语言限制，该开发工具包的 Java 实施进一步将该值限制为 2^31 - 1 或 2 吉字节 (2 GiB)。

**加密内容**  
[加密算法](algorithms-reference.md)返回的加密内容（密文）。

**身份验证标签**  
正文的身份验证值。它用于对消息正文进行身份验证。

### 帧数据
<a name="body-framing"></a>

在帧数据中，明文数据拆分为相等长度的部分（称为*帧*）。使用独特的 IV 和[主体 AA](body-aad-reference.md) D 分别 AWS Encryption SDK 加密每帧。

**注意**  
尽可能使用帧数据。仅 AWS Encryption SDK 支持传统使用的非成帧数据。的某些语言实现仍然 AWS Encryption SDK 可以生成非成帧的密文。所有支持的语言实现都可以解密成帧和非帧加密文字。

 

对于每条消息，[帧长度](#header-frame-length)（帧中的[加密内容](#body-framed-regular-content)的长度）可能是不同的。帧中的最大字节数为 2^32 - 1。消息中的最大帧数为 2^32 - 1。

共有两种类型的帧：*常规*和*最终*。每条消息必须包含最终帧或由最终帧组成。

消息中的所有常规帧具有相同的帧长度。最终帧可能具有不同的帧长度。

帧数据中的帧组成部分因加密的内容长度而异。
+ **等于帧长度** – 如果加密的内容长度与常规帧的帧长度相同，则消息可能由包含数据的常规帧以及后面的零（0）长度的最终帧组成。或者，消息可能仅由包含数据的最终帧组成。在这种情况下，最终帧的帧长度与常规帧相同。
+ **帧长度的倍数** – 如果加密的内容长度是常规帧的帧长度的整数倍数，则消息可能以包含数据的常规帧结尾，后跟零（0）长度的最终帧。或者，消息可能以包含数据的最终帧结尾。在这种情况下，最终帧的帧长度与常规帧相同。
+ **不是帧长度的倍数** – 如果加密的内容长度不是常规帧的帧长度的整数倍数，最终帧将包含其余数据。最终帧的帧长度小于常规帧的帧长度。
+ **小于帧长度** – 如果加密的内容长度小于常规帧的帧长度，则消息由包含所有数据的最终帧组成。最终帧的帧长度小于常规帧的帧长度。

下表描述了组成帧的字段。字节是按显示的顺序附加的。


**帧正文结构 - 常规帧**  

| 字段 | 长度（字节） | 
| --- | --- | 
| [Sequence Number](#body-framed-regular-sequence-number) | 4 | 
| [IV](#body-framed-regular-iv) | 变量。等于在标头的 [IV Length](#header-iv-length) 字节中指定的值。 | 
| [Encrypted Content](#body-framed-regular-content) | 变量。等于在标头的 [Frame Length](#header-frame-length) 中指定的值。 | 
| [Authentication Tag](#body-framed-regular-tag) | 变量。由使用的算法（在标头的 [Algorithm ID](#header-algorithm-id) 中指定）决定。 | 

**序列号**  
帧序列号。它是递增的帧计数器编号。这是一个解释为 32 位无符号整数的 4 字节值。  
帧数据必须从序列号 1 开始。后续的帧必须按顺序编号，并且必须在前一个帧的基础上增加 1。否则，解密过程将停止并报告错误。

**四**  
帧的初始化向量 (IV)。该开发工具包使用确定性的方法为消息中的每个帧构造不同的 IV。其长度由使用的[算法套件](algorithms-reference.md)指定。

**加密内容**  
[加密算法](algorithms-reference.md)返回的帧加密内容（密文）。

**身份验证标签**  
帧的身份验证值。它用于对整个帧进行身份验证。


**帧正文结构 - 最终帧**  

| 字段 | 长度（字节） | 
| --- | --- | 
| [Sequence Number End](#body-framed-final-sequence-number-end) | 4 | 
| [Sequence Number](#body-framed-final-sequence-number) | 4 | 
| [IV](#body-framed-final-iv) | 变量。等于在标头的 [IV Length](#header-iv-length) 字节中指定的值。 | 
| [Encrypted Content Length](#body-framed-final-content-length) | 4 | 
| [Encrypted Content](#body-framed-final-content) | 变量。等于在前 4 个字节（加密的内容长度）中指定的值。 | 
| [Authentication Tag](#body-framed-final-tag) | 变量。由使用的算法（在标头的 [Algorithm ID](#header-algorithm-id) 中指定）决定。 | 

**序列号结尾**  
最终帧的指示符。该值在十六进制表示法中编码为 4 字节 `FF FF FF FF`。

**序列号**  
帧序列号。它是递增的帧计数器编号。这是一个解释为 32 位无符号整数的 4 字节值。  
帧数据必须从序列号 1 开始。后续的帧必须按顺序编号，并且必须在前一个帧的基础上增加 1。否则，解密过程将停止并报告错误。

**四**  
帧的初始化向量 (IV)。该开发工具包使用确定性的方法为消息中的每个帧构造不同的 IV。IV 长度是由[算法套件](algorithms-reference.md)指定的。

**加密内容长度**  
加密的内容的长度。这是一个解释为 32 位无符号整数的 4 字节值，它指定包含帧加密内容的字节数。

**加密内容**  
[加密算法](algorithms-reference.md)返回的帧加密内容（密文）。

**身份验证标签**  
帧的身份验证值。它用于对整个帧进行身份验证。

## 脚注结构
<a name="footer-structure"></a>

在使用[具有签名的算法](algorithms-reference.md)时，消息格式包含脚注。消息脚注包含在消息标头和正文上计算的[数字签名](concepts.md#digital-sigs)。下表描述了组成脚注的字段。字节是按显示的顺序附加的。消息格式版本 1 和 2 中的消息脚注结构相同。


**脚注结构**  

| 字段 | 长度（字节） | 
| --- | --- | 
| [Signature Length](#footer-signature-length) | 2 | 
| [Signature](#footer-signature) | 变量。等于在前 2 个字节（签名长度）中指定的值。 | 

**签名长度**  
签名的长度。这是一个解释为 16 位无符号整数的 2 字节值，它指定包含签名的字节数。

**签名**  
签名。