本页介绍了 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 HMAC 和 AES-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_key
和 encrypted_data
值。
encapsulated_key
- 发送者的序列化公钥
- 在以下国家/地区中定义为
enc
: RFC 9180,第 4.1 节 - 格式由所使用的特定 HPKE KEM 决定
encrypted_data
- 密文和标记(即
ciphertext || tag
(不含 IV) - 在以下国家/地区中定义为
ct
: RFC 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
后跟 x
和 y
坐标为固定大小的整数。对于压缩坐标,字节 0x02
或 0x03
和 x
坐标作为固定大小的整数。对于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 P1363
或 ASN.1 DER
。
IEEE P1363
签名的格式为 r || s
,其中 r
和 s
分别是
已填充零,且大小(以字节为单位)与曲线的顺序相同。对于
例如,对于 NIST P-256
曲线,r
和 s
用零填充,得到 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 编码签名无效)。
这有助于防止特征码可塑性攻击,此类攻击通常影响 加密货币系统。