Format kabel tink

Halaman ini menjelaskan format kabel Tink untuk kunci dan output primitif. Dokumentasi ini ditujukan untuk kriptografer yang ingin menambahkan bahasa lain ke Tink dan pengelola library kripto tingkat tinggi lainnya yang menginginkan mode yang kompatibel dengan wire. Konten ini tidak ditujukan untuk audiens umum.

Serialisasi keyset

Tink menggunakan Google protobuf untuk membuat serialisasi keyset-nya.

  • Keyset serial biner adalah proto Keyset serial yang ditentukan dalam tink.proto. Properti nilai KeyData dari kunci adalah proto yang diserialisasi dari jenis kunci yang sesuai.
  • Kumpulan kunci yang diserialisasi JSON adalah proto Kumpulan kunci yang diserialisasi dalam format JSON. Perhatikan bahwa nilai KeyData masih berupa proto berseri biner.
  • Keyset terenkripsi adalah proto EncryptedKeyset yang diserialisasi dan ditentukan dalam tink.proto. File ini berisi keyset yang diserialisasi biner terenkripsi dan secara opsional beberapa metadata KeysetInfo yang tidak terenkripsi.

Awalan Output Tink

Sebagian besar primitif Tink mendukung awalan output 5 byte yang terdiri dari:

  • Versi 1 byte: 0x01
  • Petunjuk kunci 4 byte: Ini adalah ID kunci yang digunakan.

Beberapa kunci lama juga dapat mendukung byte versi 0x00.

Perhatikan bahwa awalan ini tidak diautentikasi dan tidak dapat diandalkan untuk tujuan keamanan. Tink menggunakannya sebagai petunjuk untuk mempercepat dekripsi atau verifikasi.

AEAD

Secara umum, Tink memformat ciphertext AEAD sebagai:

prefix || IV || ciphertext || tag

kecuali jika ditentukan lain dalam RFC terkait. prefix kosong atau awalan output Tink 5 byte.

AES-CTR-HMAC

Untuk AES-CTR-HMAC, Tink menghitung MAC dengan data terkait (AD) sebagai berikut:

AD || IV || ciphertext || bitlen(AD)

dengan bitlen(AD) adalah panjang AD dalam bit yang ditampilkan sebagai bilangan bulat tanpa tanda 64-bit big-endian. Skema HMAC ini mengikuti draf untuk AES-CBC-HMAC dari Mcgrew.

AEAD deterministik

Tink menerapkan RFC 5297 untuk AES-SIV, dengan menempatkan vektor inisialisasi (IV) sintetis di awal ciphertext. Primitif dapat menambahkan awalan output Tink 5 byte.

Meskipun RFC 5297 mendukung daftar data terkait, Tink hanya mendukung tepat satu data terkait, yang sesuai dengan daftar dengan satu elemen dalam RFC 5297. Data terkait yang kosong adalah daftar dengan satu elemen kosong, dan bukan daftar kosong.

Streaming AEAD

Lihat HMAC AES-CTR dan AES-GCM-HKDF.

Enkripsi alamat pengiriman

Enkripsi menyeluruh mengenkripsi data dengan kunci enkripsi data DEK menggunakan primitif AEAD Tink. Enkripsi berfungsi sebagai berikut:

  • DEK baru dibuat, menggunakan template kunci (atau parameter kunci) tertentu.
  • DEK diserialkan menjadi string byte. Format serialisasi serialisasi buffering protokol proto jenis kunci. Misalnya, ini adalah pesan buffer protokol AesGcmKey yang diserialkan yang ditentukan dalam aes_gcm.proto untuk DEK jenis kunci AES GCM. Lihat serialisasi buffering protokol untuk mengetahui cara melakukan serialisasi buffering protokol.
  • DEK yang diserialisasi dienkripsi oleh penyedia eksternal (misalnya, GCP), menjadi encrypted DEK.
  • DEK digunakan untuk mengenkripsi teks biasa dengan data terkait menjadi ciphertext. Jadi, ciphertext memiliki format yang sama persis dengan primitif AEAD yang sesuai dengan DEK.

Format output enkripsi alamat pengiriman adalah sebagai berikut:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length adalah 4 byte, yang menyimpan panjang encrypted DEK sebagai bilangan bulat big-endian 32-bit.

MAC

Tink mengikuti RFC yang sesuai. Primitif dapat menambahkan awalan output Tink 5 byte ke tag.

Set PRF

Tink mengikuti RFC yang sesuai. Perhatikan bahwa untuk PRF, jenis kunci berbeda dari jenis kunci MAC dengan algoritma yang sama karena tidak menyertakan panjang output. Kunci Set PRF tidak pernah menambahkan awalan output Tink. Hal ini memastikan outputnya benar-benar PRF.

Enkripsi hybrid

Format kabel umum untuk enkripsi hybrid Tink adalah sebagai berikut:

prefix || encapsulated_key || encrypted_data

prefix kosong atau merupakan awalan output Tink 5 byte. Setiap jenis kunci berisi informasi tentang jumlah byte yang akan diuraikan, dan cara menguraikan byte tersebut dari encapsulated_key.

HPKE (Hybrid Public Key Encryption)

Tink mengikuti standar HPKE yang ditentukan dalam RFC 9180. Ciphersuite HPKE mencakup tiga primitif berikut.

  • Mekanisme enkapsulasi kunci (KEM)
  • Fungsi turunan kunci (KDF)
  • Enkripsi yang diautentikasi dengan data terkait (AEAD)

Standar HPKE tidak menentukan format wire umum dalam RFC 9180, Bagian 10. Implementasi HPKE Tink menggunakan nilai encapsulated_key dan encrypted_data berikut.

  • encapsulated_key
    • Kunci publik berserial pengirim
    • Ditentukan sebagai enc dalam RFC 9180, Bagian 4.1
    • Format ditentukan oleh KEM HPKE spesifik yang digunakan
  • encrypted_data
    • Teks tersandi dan tag (yaitu, ciphertext || tag tanpa IV)
    • Didefinisikan sebagai ct dalam RFC 9180, Bagian 4
    • Format ditentukan oleh AEAD HPKE tertentu yang digunakan
KEM berbasis Diffie-Hellman X25519

Untuk DHKEM X25519, nilai enc adalah kunci publik Diffie-Hellman 32 byte pengirim.

ECIES-AEAD-HKDF

Untuk penerapan ECIES-AEAD-HKDF Tink, encapsulated_key adalah output dari Key Encapsulation Mechanism (KEM) dan encrypted_data adalah output dari Data Encapsulation Mechanism (DEM).

KEM

Bergantung pada jenis kunci, Tink menggunakan titik kurva elips terkompresi dan tidak terkompresi, mengikuti standar encoding RFC 8422/ANSI.X9-62.2005. Untuk titik yang tidak dikompresi, byte 0x04 diikuti dengan koordinat x dan y sebagai bilangan bulat berukuran tetap. Untuk koordinat terkompresi, byte 0x02 atau 0x03 dan koordinat x sebagai bilangan bulat berukuran tetap digunakan. Untuk X25519, definisi RFC 7748 digunakan (koordinat x sebagai bilangan bulat berukuran tetap).

DEM

Untuk encrypted_data, Tink menggunakan format yang sama dengan AEAD. Hal ini mencakup penentuan IV.

Turunan kunci

Pertama, koordinat x x_ss dari titik bersama dihitung. Kunci untuk AEAD kemudian ditetapkan ke:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

dengan encapsulated_key adalah output KEM lengkap sebagai byte.

Tanda tangan digital

Tink mengikuti RFC yang sesuai. Primitif dapat menambahkan awalan output Tink 5 byte ke tag yang dihasilkan.

ECDSA

Bergantung pada EcdsaSignatureEncoding field di kunci, format tanda tangan ECDSA adalah IEEE P1363 atau ASN.1 DER.

Format tanda tangan IEEE P1363 adalah r || s, dengan r dan s diisi dengan nol dan memiliki ukuran dalam byte yang sama dengan urutan kurva. Misalnya, untuk kurva NIST P-256, r dan s diisi dengan nol hingga 32 byte.

Tanda tangan DER dienkode menggunakan ASN.1:

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

Secara khusus, encoding-nya adalah:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink mengikuti praktik terbaik untuk verifikasi tanda tangan, dengan hanya menerima tanda tangan ECDSA yang dienkode DER (tanda tangan yang dienkode BER alternatif tidak valid).

Hal ini membantu mencegah serangan perubahan tanda tangan, yang sering memengaruhi sistem mata uang kripto.

Nilai pra-hash ML-DSA Mu eksternal

Primitif Prehash mengubah pesan menjadi nilai pra-hash, yang kemudian ditandatangani oleh primitif SignPrehash. Untuk ML-DSA dalam mode External Mu, seperti yang dijelaskan dalam RFC 9881, nilai pra-hash adalah 69 byte dengan tata letak berikut:

0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
  • mu adalah representasi pesan ML-DSA, yang dihitung sebagai SHAKE256(tr || 0x00 || 0x00 || message, 64), dengan tr adalah hash 64 byte kunci publik, 0x00 pertama adalah pemisah domain FIPS 204 untuk ML-DSA murni, dan 0x00 kedua adalah panjang string konteks (kosong). Karena tr berasal dari kunci publik, mu terikat secara kriptografis ke kunci tersebut -- meskipun memeriksa pengikatan memerlukan pesan asli.
  • Awalan 5 byte adalah pembingkaian Tink, bukan bagian dari mu. Hal ini mengaitkan nilai pra-hash dengan satu kunci tertentu, sehingga SignPrehash mengetahui kunci mana yang akan digunakan untuk menandatangani dan dapat menolak nilai pra-hash yang tidak memiliki kunci. Awalan adalah metadata biasa dan tidak mengikat apa pun secara kriptografis: siapa pun dapat menulis ulang awalan tersebut.

Penandatanganan menolak input apa pun yang tidak berukuran tepat 69 byte, yang tidak dimulai dengan 0xff, atau yang ID kuncinya tidak cocok dengan kunci yang diaktifkan dalam set kuncinya.