Tink 線路格式

本頁說明 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 HMACAES-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_keyencrypted_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 後面接著 xy 座標,以固定大小整數表示。針對壓縮座標,則會使用位元組 0x020x03 以及 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 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 編碼的簽名無效)。

這有助於防範簽章的購物中心式攻擊,這類攻擊通常會影響加密貨幣系統