Tink ワイヤーの形式

このページでは、鍵とプリミティブ出力の 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 HMACAES-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_keyencrypted_data 値を使用します。

  • encapsulated_key
    • 送信者のシリアル化された公開鍵
    • RFC 9180、セクション 4.1enc として定義されています。
    • 使用する特定の HPKE KEM によって形式が決まります
  • encrypted_data
    • 暗号テキストとタグ(ciphertext || tag(IV なし)
    • RFC 9180、セクション 4ct として定義されています。
    • 使用される特定の 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 です。ここで、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 エンコードされた代替署名は無効です)。

これにより、暗号通貨システムに影響することが多い署名の順応性攻撃を防ぐことができます。