Keyset

Tink menggunakan Keyset untuk mengaktifkan rotasi kunci. Secara formal, keyset adalah daftar kunci1 yang tidak kosong, dengan satu kunci ditetapkan sebagai 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 untuk menonaktifkan kunci tanpa menghapusnya dari keyset.

Kumpulan kunci adalah cara utama bagi pengguna untuk mengakses kunci (melalui class KeysetHandle). Hal ini memastikan bahwa setiap pengguna memiliki kode untuk menangani beberapa kunci sekaligus. Bagi sebagian besar pengguna kriptografi, menangani beberapa kunci adalah keharusan: kunci harus dapat diubah (kunci lama dapat bocor, misalnya), dan hampir tidak pernah ada "beralih ke kunci berikutnya" atomik yang dapat diterapkan ke mesin tempat kode berjalan dan semua ciphertext, secara global, dan dalam sekejap. Oleh karena itu, pengguna perlu menulis kode yang berfungsi saat pengguna beralih dari satu tombol ke tombol berikutnya.

Contoh: AEAD

Pertimbangkan kumpulan kunci AEAD, yang berisi beberapa kunci untuk primitif AEAD. Seperti yang dijelaskan sebelumnya, setiap kunci menentukan dua fungsi secara unik: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\). Kumpulan kunci kini juga menentukan dua fungsi baru: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) - \(\mathrm{Enc}\) hanya sama dengan fungsi \(\mathrm{Enc}\) kunci utama kumpulan kunci, sedangkan fungsi \(\mathrm{Dec}\) mencoba mendekripsi dengan semua kunci, dengan memeriksa kunci tersebut dalam beberapa urutan (lihat di bawah untuk mengetahui cara Tink meningkatkan performa hal ini).

Perlu diperhatikan bahwa Keyset adalah kunci lengkap: kunci ini adalah deskripsi lengkap fungsi \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) yang digunakan. Artinya, pengguna dapat menulis class yang menggunakan KeysetHandle sebagai input, yang mengekspresikan ide bahwa class memerlukan deskripsi objek lengkap \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) agar dapat berfungsi dengan benar. Hal ini memungkinkan pengguna menulis API yang menyampaikan bahwa: untuk menggunakan class ini, Anda harus memberikan deskripsi primitif kriptografis kepada saya.

Rotasi kunci

Pertimbangkan pengguna Tink, yang menulis program yang pertama kali mendapatkan kumpulan kunci dari KMS, lalu membuat objek AEAD dari kumpulan kunci ini, dan akhirnya menggunakan objek ini untuk mengenkripsi dan mendekripsi ciphertext.

Pengguna tersebut akan otomatis disiapkan untuk rotasi kunci; dan beralih algoritma jika pilihannya saat ini tidak lagi memenuhi standar.

Namun, Anda harus berhati-hati saat menerapkan rotasi kunci tersebut: Pertama, KMS harus menambahkan kunci baru ke kumpulan kunci (tetapi belum menetapkannya sebagai utama). Kemudian, kumpulan kunci baru perlu diluncurkan ke semua biner, sehingga setiap biner yang menggunakan kumpulan kunci ini memiliki kunci terbaru dalam kumpulan kunci. Setelah itu, kunci baru harus dibuat utama, dan keyset yang dihasilkan akan didistribusikan lagi ke semua biner yang menggunakan keyset.

ID kunci dalam ciphertext

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

Oleh karena itu, Tink memungkinkan awalan ciphertext dengan string 5 byte yang berasal dari ID. Dengan mengikuti filosofi 'Kunci Lengkap' di atas, awalan ini adalah bagian dari kunci, dan semua ciphertext yang pernah berasal dari kunci ini harus memiliki awalan ini. Saat membuat kunci, pengguna dapat memilih apakah kunci harus menggunakan awalan tersebut, atau apakah format ciphertext tanpa awalan tersebut harus digunakan.

Saat kunci berada dalam keyset, Tink akan menghitung tag ini dari ID yang dimiliki kunci dalam keyset. Fakta bahwa ID bersifat unik2 dalam kumpulan kunci menyiratkan bahwa tag bersifat unik. Oleh karena itu, jika hanya kunci yang diberi tag yang digunakan, tidak ada hilangnya 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 ada dalam kumpulan kunci jika memiliki satu ID tertentu. Hal ini memiliki beberapa implikasi saat menjelaskan implementasi objek kunci dalam bahasa yang berbeda.


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

  2. Untuk kompatibilitas dengan library internal Google, Tink memungkinkan untuk memiliki kumpulan kunci tempat ID diulang. Dukungan ini akan dihapus pada masa mendatang.