このページでは、鍵とプリミティブ出力の Tink のワイヤ形式について説明します。このドキュメントは、Tink に言語を追加する暗号担当者と、ワイヤー互換モードを必要とする他の高レベル暗号ライブラリのメンテナンス担当者を対象としています。一般向けではありません。
キーセットのシリアル化
Tink は Google protobuf を使用して鍵セットをシリアル化します。
- シリアル化されたバイナリキーセットは、tink.proto で定義されているシリアル化された Keyset プロトコルです。キーの KeyData 値プロパティは、対応するキータイプのシリアル化された proto です。
- JSON にシリアル化されたキーセットは、JSON 形式でシリアル化された Keyset proto です。KeyData 値は、引き続きバイナリのシリアル化された proto です。
- 暗号化された鍵セットは、tink.proto で定義されているシリアル化された EncryptedKeyst プロトコルです。これには、暗号化されたバイナリにシリアル化された鍵セットと、必要に応じて暗号化されていない 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)
は、64 ビット ビッグ エンディアンの符号なし整数として表される AD の長さのビット数です。この HMAC スキームは、Mcgrew からの AES-CBC-HMAC のドラフトに従います。
決定論的 AEAD
Tink は AES-SIV の RFC 5297 を実装し、暗号テキストの先頭に合成初期化ベクトル(SIV)を配置します。プリミティブは、5 バイトの Tink 出力接頭辞を追加できます。
RFC 5297 では関連データのリストがサポートされていますが、Tink がサポートする関連データは 1 つのみで、RFC 5297 では 1 つの要素を含むリストに対応します。空の関連データは、空の要素が 1 つ含まれるリストであり、空のリストではありません。
ストリーミング AEAD
AES-CTR HMAC と AES-GCM-HKDF をご覧ください。
エンベロープ暗号化
エンベロープ暗号化は、Tink の AEAD プリミティブを使用して、データ暗号鍵 DEK
でデータを暗号化します。暗号化は次のように行われます。
- 指定されたキー テンプレート(またはキーパラメータ)を使用して、新しい
DEK
が生成されます。 DEK
はバイト文字列にシリアル化されます。シリアル化形式で、キー型の proto のプロトコル バッファをシリアル化します。たとえば、aes_gcm.proto で定義されている、キータイプ AES GCM の DEK 用にシリアル化されたAesGcmKey
プロトコル バッファ メッセージです。プロトコル バッファをシリアル化する方法については、プロトコル バッファのシリアル化をご覧ください。- シリアル化された
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 Set 鍵には、Tink 出力接頭辞は追加されません。これにより、出力が実際に PRF になります。
ハイブリッド暗号化
Tink ハイブリッド暗号化の一般的な送信形式は次のとおりです。
prefix || encapsulated_key || encrypted_data
prefix
は、空または 5 バイトの Tink 出力接頭辞です。各キータイプには、解析するバイト数と、encapsulated_key
からのバイト数を解析する方法に関する情報が含まれています。
HPKE(ハイブリッド公開鍵暗号化)
Tink は、RFC 9180 で定義されている HPKE 標準に従っています。HPKE 暗号スイートには、次の 3 つのプリミティブが含まれています。
- 鍵カプセル化メカニズム(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
として定義されています。 - 使用される特定の HPKE AEAD によって決定される形式
- 暗号テキストとタグ(
X25519 Diffie-Hellman ベースの KEM
X25519 DHKEM の場合、値 enc
は送信元の 32 バイトの Diffie-Hellman 公開鍵です。
ECIES-AEAD-HKDF
Tink の ECIES-AEAD-HKDF 実装では、encapsulated_key
は鍵カプセル化メカニズム(KEM)の出力、encrypted_data
はデータ カプセル化メカニズム(DEM)の出力です。
KEM
Tink は、鍵タイプに応じて、RFC 8422/ANSI.X9-62.2005
エンコード規格に従って、圧縮および非圧縮の楕円曲線ポイントを使用します。非圧縮ポイントの場合、バイト 0x04
の後に、固定サイズの整数として x
座標と y
座標が続きます。圧縮座標の場合、バイト 0x02
または 0x03
と、固定サイズの整数として x
座標が使用されます。X25519
には RFC 7748 定義が使用されます(固定サイズの整数として x
座標)。
DEM
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 エンコードされた代替署名は無効です)。
これにより、暗号通貨システムに影響することが多い署名の順応性攻撃を防ぐことができます。