Tink 线格式

本页介绍了 Tink 的密钥和基元输出的传输格式。通过 文档主要面向希望在 Google Cloud 中添加其他语言的密码学家 需要连接的其他高级加密库的 Tink 和维护人员 兼容模式。不适合一般观众。

密钥集序列化

Tink 使用 Google protobuf 来序列化其密钥集。

  • 二进制序列化密钥集是在 tink.proto.键的 KeyData 值属性是序列化的 proto。
  • JSON 序列化密钥集是以 JSON 格式序列化的密钥集原型。 请注意,KeyData 值仍然是二进制序列化 proto。
  • 已加密的密钥集是在 中定义的序列化 EncryptedKeyst proto tink.proto.它包含一个加密的二进制序列化密钥集 以及一些未加密的 KeysetInfo 元数据。

Tink 输出前缀

大多数 Tink 基元支持 5 字节输出前缀,其中包括:

  • 1 字节版本:0x01
  • 4 个字节的键提示:这是所用键的 ID。

某些旧版密钥可能也支持版本字节 0x00

请注意,此前缀未经身份验证,不能据此确保安全性 目的。Tink 将其用作加快解密或验证速度的提示。

AEAD

通常,Tink 会将 AEAD 密文的格式设置为:

prefix || IV || ciphertext || tag

除非相应的 RFC 中另有规定。“prefix”为空 或 5 字节的 Tink 输出前缀。

AES-CTR-HMAC

对于 AES-CTR-HMAC,Tink 会按如下方式计算包含相关数据 (AD) 的 MAC:

AD || IV || ciphertext || bitlen(AD)

其中,bitlen(AD) 是 AD 的长度(以位为单位),以 64 位大端序表示 无符号整数。此 HMAC 架构遵循 AES-CBC-HMAC Mcgrew.

确定性 AEAD

Tink 实现了针对 AES-SIV 的 RFC 5297,将合成 加密向量 (SIV)。 基元可以添加一个 5 字节的 Tink 输出前缀。

虽然 RFC 5297 支持相关数据列表,但 Tink 仅支持 一个关联数据,对应于 RFC 5297 中包含一个元素的列表。 空关联数据是指包含一个空元素(而非空元素)的列表 列表。

流式 AEAD

请参阅 AES-CTR HMACAES-GCM-HKDF

信封加密

信封加密使用数据加密密钥 DEK 对数据进行加密,方法是: Tink 的 AEAD 基元。加密的工作原理如下:

  • 系统会使用给定的密钥模板(或密钥参数)生成新的 DEK
  • DEK 被序列化为字节字符串。该 密钥类型 proto 的协议缓冲区序列化。例如,这是一个 序列化AesGcmKey协议缓冲区消息, aes_gcm.proto,适用于 AES GCM 密钥类型的 DEK。 如需了解如何序列化,请参阅协议缓冲区序列化 协议缓冲区
  • 序列化的 DEK 由外部提供方(例如 GCP)加密, 转换为 encrypted DEK
  • DEK 用于加密包含关联数据的明文, ciphertext。因此,ciphertext 的格式与 AEAD 基元完全相同 与 DEK 相对应。

信封加密的输出格式如下所示:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length 为 4 个字节,用于存储 encrypted DEK 的长度 为 32 位大端序整数。

MAC

Tink 遵循相应的 RFC。基元可以添加 5 字节的 Tink 输出 前缀。

PRF 集

Tink 遵循相应的 RFC。请注意,对于 PRF Set,密钥类型 从同一算法的 MAC 密钥类型中提取 MAC 密钥类型。 PRF 集密钥从不添加 Tink 输出前缀。这样可以确保 PRF。

混合加密

Tink 混合加密的常规传输格式如下:

prefix || encapsulated_key || encrypted_data

prefix 为空或 5 字节的 Tink 输出前缀。每种密钥类型都包含 需要解析多少字节以及如何从 encapsulated_key

HPKE(混合公钥加密)

Tink 遵循 RFC 9180 中定义的 HPKE 标准。 HPKE 加密套件包含以下三个基元。

  • 密钥封装机制 (KEM)
  • 密钥推导函数 (KDF)
  • 使用关联数据进行身份验证的加密 (AEAD)

HPKE 标准在 RFC 9180 第 10。Tink 的 HPKE 实现使用以下 encapsulated_keyencrypted_data 值。

  • encapsulated_key
    • 发送者的序列化公钥
    • 在以下国家/地区中定义为 encRFC 9180,第 4.1 节
    • 格式由所使用的特定 HPKE KEM 决定
  • encrypted_data
    • 密文和标记(即ciphertext || tag(不含 IV)
    • 在以下国家/地区中定义为 ctRFC 9180,第 4 节
    • 格式由所使用的特定 HPKE AEAD 决定
X25519 基于 Diffie-Hellman 的 KEM

对于 X25519 DHKEM,值 enc 是发件人的 32 字节 Diffie-Hellman 公开 键。

ECIES-AEAD-HKDF

对于 Tink 的 ECIES-AEAD-HKDF 实现,encapsulated_key 是输出 encrypted_data 是密钥封装机制 (KEM) 的输出 数据封装机制 (DEM) 的技术。

KEM

Tink 会使用压缩和未压缩的椭圆曲线,具体取决于密钥类型 符合 RFC 8422/ANSI.X9-62.2005 编码标准。对于 未压缩的点,字节 0x04 后跟 xy 坐标为固定大小的整数。对于压缩坐标,字节 0x020x03x 坐标作为固定大小的整数。对于X25519, 系统将使用 RFC 7748 定义(x 坐标为固定大小的整数)。

德国马克

对于 encrypted_data,Tink 使用与 AEAD 相同的格式。这包括 指定 IV。

密钥派生

首先,计算共享点的 x 坐标 x_ss。此 然后,AEAD 会设置为:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

其中 encapsulated_key 是以字节为单位的完整 KEM 输出。

数字签名

Tink 遵循相应的 RFC。基元可以添加 5 字节的 Tink 输出 前缀。

ECDSA

根据密钥中的 EcdsaSignatureEncoding 字段, ECDSA 签名的格式为 IEEE P1363ASN.1 DER

IEEE P1363 签名的格式为 r || s,其中 rs 分别是 已填充零,且大小(以字节为单位)与曲线的顺序相同。对于 例如,对于 NIST P-256 曲线,rs 用零填充,得到 32 个字节。

DER 签名使用 ASN.1 进行编码:

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

具体来说,编码为:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink 遵循签名验证的最佳实践, DER 编码的 ECDSA 签名(备用的 BER 编码签名无效)。

这有助于防止特征码可塑性攻击,此类攻击通常影响 加密货币系统