規律上傳

請務必確保所有程式設計語言中的 Tink 行為都是「相同」的。這個概念並不簡單,但最重要的是:

為維持一致性,Tink 採用跨語言 GitHub 存放區中的跨語言測試。這些測試可驗證不同語言的一致性和互通性。

但是,定義一致性並不如預期簡單。因此,本頁面提供的工作定義。基本上,Tink 提供兩種一致性:

內容脈絡

整體來說,Tink 提供下列 API:

  • 金鑰組操控:Tink 提供的 API 可用來將新金鑰新增至金鑰組、從金鑰組移除金鑰,以及變更金鑰組中的主鍵。

  • 金鑰組序列化:Tink 提供 API 將金鑰組序列化為位元組序列,並反向剖析位元組序列的金鑰組。

  • 原始建立:Tink 提供的 API 可以為透過金鑰組建立原始介面建立介面。舉例來說,如要在 Java 中透過金鑰組建立 Aead 物件,使用者會呼叫 keysetHandle.getPrimitive(Aead.class, config)

  • 原始使用:在原始建立步驟中產生的介面會提供 API,以執行加密編譯作業。

關於這些 API,請思考以下兩個重要問題:

  • 建立: 對於特定的序列化金鑰組、語言和原始版本,是否可以使用特定語言以這個金鑰組建立原始版本?

  • 評估:如果可從特定金鑰組以某些語言建立原始物件,原始物件會如何運作?

請特別注意,剖析金鑰組時,Tink 不提供一致性。舉例來說,Tink C++

  • 成功剖析包含 CHACHA20-POLY1305 金鑰的金鑰組,即使 Tink 並未實作 CHACHA20-POLY1305 AEAD 作業也一樣。
  • 已成功剖析含有長度為 1 位元組的金鑰組,但所有加密編譯作業都會失敗。

這些行為可能會在子版本中有所改變。

評估一致性

評估一致性比建立程序中的任何一致性更為重要:如果 Java 中的 AEAD 無法將 C++ 中的 AEAD 加密解密,使用者就會遇到嚴重的問題。

一般來說,Tink 旨在讓原始檔案保持一致。舉例來說,如果 C++ 二進位檔會使用 public_key_sign->Sign(data) 計算簽名,對應的 Java 驗證呼叫 publicKeyVerify.verify(signature, data) 就會成功。

不過,就算如此,這裡還是有些注意事項。舉例來說,Java 中的 aead.Encrypt 傳回類型為 byte[]。根據 Java 語言規格 (JLS) §10.7,陣列的長度可以是 int 類型,根據 §JLS 4.2.1 的規定,大小上限為 2147483647。因此,在 Java 中,加密長度為 2147483647 的陣列會失敗:加密會產生一些負擔,代表輸出過長。然而,如果是其他語言,仍可加密處理。

因此,Tink 提供的評估一致性:如果特定金鑰組成功透過兩種語言建立原始組合,則兩者的行為相同。

例外狀況:某些作業在某些情況下可能會失敗。

創作一致性

並非所有金鑰組都成功建立原始物件。舉例來說,如果金鑰內容的長度為 128 位元,Tink 不允許使用者建立 AesSivKey。

儘管如此,Tink 還是會提供以下一致性:如果兩種語言都同時支援金鑰類型,就可以建立原始組合的一組金鑰。當然,如果語言不支援金鑰類型,您就無法建立原始物件。

建立一致性比評估一致性更低,而且這項規則的例外狀況比評估一致性還多。這些限制都已記錄在支援的金鑰類型清單中。舉例來說,金鑰類型 ECIES Tink 提供用於金鑰協議的橢圓曲線選擇,但 Java 不支援 X25519。因此,在 Java 中使用 X25519 建立金鑰會失敗。


  1. 在本文件中,我們使用 Keyset 一詞來表示大多數語言中名為 KeysetHandle 的物件。