Keyset

Tink menggunakan Keyset untuk mengaktifkan rotasi kunci. Secara formal, keyset adalah daftar 1 kunci yang tidak kosong, yang mana satu kunci ditetapkan sebagai kunci utama (kunci yang digunakan misalnya untuk menandatangani dan mengenkripsi teks biasa baru). Selain itu, kunci dalam keyset mendapatkan ID unik2 dan status kunci yang memungkinkan menonaktifkan kunci tanpa menghapusnya dari keyset.

Keyset adalah cara utama yang dapat digunakan pengguna untuk mengakses kunci (melalui class KeysetHandle). Ini memastikan bahwa setiap pengguna memiliki kode untuk menangani beberapa kunci sekaligus. Bagi sebagian besar pengguna kriptografi, penanganan beberapa kunci adalah keperluan: kunci lama harus dapat diubah (misalnya, kunci lama dapat dibocorkan), dan hampir tidak pernah ada "beralih ke kunci berikutnya" atomik yang dapat diterapkan ke mesin yang dijalankan kode dan semua teks tersandi, secara global dan instan. Oleh karena itu, pengguna perlu menulis kode yang berfungsi saat satu kunci berubah dari satu kunci ke kunci berikutnya.

Contoh: AEAD

Pertimbangkan kumpulan kunci AEAD yang berisi beberapa kunci untuk primitif AEA. Seperti yang dijelaskan sebelumnya, setiap tombol secara unik menentukan dua fungsi: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\). Kini keyset juga menentukan dua fungsi baru: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) - \(\mathrm{Enc}\) hanya sama dengan fungsi \(\mathrm{Enc}\) kunci utama keyset, sementara fungsi \(\mathrm{Dec}\) mencoba mendekripsi dengan semua kunci, melewatinya dalam urutan tertentu (lihat di bawah untuk mengetahui cara Tink meningkatkan performa ini).

Sangat menarik untuk diperhatikan bahwa Keyset adalah kunci lengkap: yang merupakan deskripsi lengkap fungsi \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) digunakan. Artinya, pengguna dapat menulis class yang digunakan sebagai input KeysetHandle, yang menyatakan bahwa class tersebut memerlukan deskripsi objek yang lengkap \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) agar berfungsi dengan benar. Dengan begitu, pengguna dapat menulis API yang mengomunikasikan hal tersebut: untuk menggunakan class ini, Anda harus memberi saya deskripsi dasar kriptografi.

Rotasi kunci

Misalkan seorang pengguna Tink menulis program yang pertama-tama memperoleh keyset dari KMS, lalu membuat objek AEAD dari keyset ini, dan akhirnya menggunakan objek ini untuk mengenkripsi dan mendekripsi ciphertext.

Pengguna tersebut secara otomatis siap untuk rotasi kunci; dan beralih algoritma jika pilihan mereka saat ini tidak lagi memenuhi standar.

Kita harus berhati-hati saat menerapkan rotasi kunci tersebut: Pertama, KMS harus menambahkan kunci baru ke keyset (tetapi belum menetapkannya sebagai kunci utama). Kemudian, keyset baru tersebut perlu diluncurkan ke semua biner, sehingga setiap biner yang menggunakan keyset ini memiliki kunci terbaru dalam keyset tersebut. Hanya dengan cara ini, kunci baru dapat dijadikan sebagai utama, dan keyset yang dihasilkan akan didistribusikan kembali ke semua biner yang menggunakan keyset tersebut.

ID kunci dalam teks tersandi

Pertimbangkan lagi contoh keyset AEAD. Jika dilakukan secara naif, dekripsi ciphertext mengharuskan Tink untuk mencoba mendekripsi dengan semua kunci dalam Keyset karena tidak ada cara untuk mengetahui kunci mana yang digunakan untuk mengenkripsi keyset tersebut. Hal ini dapat menyebabkan overhead performa yang besar.

Karena itu, Tink memungkinkan awalan ciphertext dengan string 5 byte yang berasal dari ID. Mengikuti filosofi 'Full Keys' di atas, awalan ini adalah bagian dari kunci, dan semua ciphertext yang pernah diturunkan dengan kunci ini harus memiliki awalan ini. Saat membuat kunci, mereka dapat memilih apakah kunci tersebut harus menggunakan awalan tersebut, atau apakah format ciphertext tanpanya harus digunakan.

Jika kunci berada dalam keyset, Tink akan menghitung tag ini dari ID yang dimiliki kunci tersebut di keyset. Fakta bahwa ID bersifat unik2 dalam keyset menyiratkan bahwa tag tersebut unik. Oleh karena itu, jika hanya kunci yang diberi tag yang digunakan, tidak ada kerugian performa dibandingkan dengan mendekripsi dengan satu kunci: Tink hanya perlu mencoba salah satu kunci saat mendekripsi.

Namun, karena tag adalah bagian dari kunci, hal ini juga menyiratkan bahwa kunci hanya dapat berada dalam keyset jika memiliki satu ID khusus. Hal ini memiliki beberapa implikasi saat menjelaskan implementasi objek utama dalam bahasa yang berbeda.


  1. Beberapa bagian dari Tink masih memperlakukan Keyset sebagai satu set. Namun, hal ini harus diubah. Alasannya karena urutan tersebut secara umum penting: misalnya, pertimbangkan siklus proses umum rotasi kunci dengan Aead. Pertama, kunci baru ditambahkan ke keyset. Kunci ini belum dijadikan utama, tetapi aktif. Keyset baru ini diluncurkan ke semua biner. Setelah semua biner mengetahui kunci baru tersebut, kunci tersebut akan dijadikan sebagai utama (hanya pada tahap ini menggunakan kunci ini akan aman). Pada langkah kedua ini, rotasi kunci perlu mengetahui kunci terakhir yang ditambahkan. 

  2. Untuk kompatibilitas dengan library internal Google, Tink memungkinkan set kunci untuk pengulangan ID. Dukungan ini akan dihapus pada masa mendatang.