本頁說明 Tink 的按鍵和基本輸出傳輸格式。這份說明文件的適用對象,是希望為其他高階加密程式庫 (而且想使用有線相容模式) 新增其他語言的 Tink 和維護者。不適合一般大眾。
金鑰組序列化
Tink 會使用 Google protobuf 進行序列化的金鑰組。
- 二進位序列化金鑰組是在 tink.proto 中定義的序列化 Keyset proto。金鑰的 KeyData 值屬性是對應金鑰類型的序列化原型。
- JSON 序列化金鑰組是以 JSON 格式序列化的 Keyset proto。請注意,KeyData 值仍然是二進位經過序列化的 proto。
- 加密金鑰組是在 tink.proto 中定義的序列化 EncryptedKeyst proto。這個檔案包含已加密的二進位檔序列化金鑰組,以及選用的部分未加密 KeysetInfo 中繼資料。
Tink 輸出前置字串
大多數的 Tink 原始物件都支援 5 位元組的輸出前置字串,當中包含:
- 1 位元組版本:
0x01
- 4 個位元組金鑰提示:這是所用金鑰的索引鍵 ID。
部分舊版金鑰可能也支援版本位元組 0x00
。
請注意,這個前置字串並未經過驗證,且無法將其依賴於安全考量。Tink 會將其做為提示,用於加快解密或驗證作業。
阿拉伯聯合大公國
一般來說,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 配置遵循 Mcgrew 的 AES-CBC-HMAC 草稿。
確定性 AEAD
Tink 針對 AES-SIV 實作 RFC 5297,將合成初始化向量 (SIV) 放在密文的開頭。基本可能會新增 5 位元組的 Tink 輸出前置字串。
雖然 RFC 5297 支援關聯資料清單,但 Tink 只支援一個相關聯的資料,對應的是一份 RFC 5297 中元素的清單。空白關聯資料是一個空白元素的清單,而不是空白清單。
串流 AEAD
請參閱 AES-CTR HMAC 和 AES-GCM-HKDF。
信封式加密
信封式加密會使用 Tink 的 AEAD 基元,以資料加密金鑰 DEK
加密資料。加密作業的運作方式如下:
- 系統會使用指定的鍵範本 (或鍵參數) 產生新的
DEK
。 DEK
會序列化為位元組字串。序列化格式是金鑰類型 proto 的通訊協定緩衝區序列化格式。舉例來說,這是在 aes_gcm.proto 中定義的序列化AesGcmKey
通訊協定緩衝區訊息,適用於金鑰類型 AES GCM。如要瞭解如何將通訊協定緩衝區序列化,請參閱通訊協定緩衝區序列化。- 序列化的
DEK
會由外部供應商 (例如 GCP) 加密,並轉換成encrypted DEK
。 DEK
的用途是將相關聯資料的明文加密到ciphertext
。因此,ciphertext
的格式與與DEK
對應的 AEAD 原始版本相同。
信封加密的輸出格式如下:
encrypted DEK length || encrypted DEK || ciphertext
encrypted DEK length
是 4 個位元組,會將 encrypted DEK
的長度儲存為 32 位元大端序的整數。
MAC
Tink 符合對應的 RFC。基本功能可能會在標記中加入 5 位元組的 Tink 輸出前置字串。
PRF 組
Tink 符合對應的 RFC。請注意,如果是 PRF,因為不包含輸出長度,設定金鑰類型與相同演算法的 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
- 傳送者的序列化公開金鑰
- 在 RFC 9180 第 4.1 節中定義為
enc
- 格式取決於所用特定 HPKE KEM
encrypted_data
- 加密和標記 (即
ciphertext || tag
(不含 IV) - 在 RFC 9180 第 4 節中定義為
ct
- 格式取決於所用特定 HP AEAD
- 加密和標記 (即
X25519 Diffie-Hellman - KEM
如果是 X25519 DHKEM,enc
值為傳送方的 32 位元組 Diffie-Hellman 公開金鑰。
ECIES-AEAD-HKDF
對於 Tink 的 ECIES-AEAD-HKDF 實作項目,encapsulated_key
是金鑰封裝機制 (KEM) 的輸出內容,而 encrypted_data
則是資料封裝機制 (DEM) 的輸出內容。
肯亞先令
視金鑰類型而定,Tink 會根據 RFC 8422/ANSI.X9-62.2005
編碼標準使用壓縮及未壓縮的橢圓曲線點。如果是未壓縮的點,位元組 0x04
後面接著 x
和 y
座標,以固定大小整數表示。針對壓縮座標,則會使用位元組 0x02
或 0x03
以及 x
座標做為固定大小整數。如果是 X25519
,會使用 RFC 7748 定義 (以固定大小整數表示的 x
座標)。
德蘭薩諸塞州
Tink 為 encrypted_data
採用與 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 編碼的簽名無效)。
這有助於防範簽章的購物中心式攻擊,這類攻擊通常會影響加密貨幣系統。