このページでは、鍵とプリミティブ出力の Tink のワイヤー形式について説明します。このドキュメントは、Tink に言語を追加する暗号学者と、ワイヤー互換モードを希望する他の高レベル暗号ライブラリのメンテナを対象としています。一般の視聴者を対象としたものではありません。
鍵セットのシリアル化
Tink は Google protobuf を使用して鍵セットをシリアル化します。
- バイナリでシリアル化された鍵セットは、tink.proto で定義されたシリアル化された Keyset proto です。キーの KeyData 値プロパティは、対応するキータイプのシリアル化されたプロトコルです。
- JSON シリアル化されたキーセットは、JSON 形式でシリアル化された Keyset proto です。KeyData の値は、引き続きシリアル化されたバイナリ プロトコルです。
- 暗号化された鍵セットは、tink.proto で定義されたシリアル化された EncryptedKeyset proto です。暗号化されたバイナリ シリアル化されたキーセットと、必要に応じて暗号化されていない 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 の DEK 用に aes_gcm.proto で定義されたシリアル化された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 Set の場合、鍵のタイプは出力の長さを含まないことで、同じアルゴリズムの MAC 鍵のタイプとは異なります。PRF セットキーには 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 でエンコードされた代替署名は無効です)。
これにより、暗号通貨システムに影響する署名の改ざん攻撃を防ぐことができます。