Tink menggunakan Kumpulan Kunci untuk mengaktifkan rotasi kunci. Secara formal, keyset adalah daftar1 kunci yang tidak kosong dengan satu kunci yang 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 penonaktifan kunci tanpa menghapusnya dari keyset.
Kumpulan kunci adalah cara utama pengguna dapat 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
suatu keharusan: kunci harus dapat diubah (misalnya, kunci lama dapat bocor), dan hampir tidak pernah ada "beralih ke kunci berikutnya" secara 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 beralih dari satu kunci ke kunci berikutnya.
Contoh: AEAD
Pertimbangkan set kunci AEAD, yang berisi beberapa kunci untuk primitif AEAD. Seperti yang dijelaskan sebelumnya, setiap kunci secara unik menentukan dua fungsi: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\). Kumpulan kunci kini juga menentukan dua fungsi baru: \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) - \(\mathrm{Enc}\) sama dengan fungsi \(\mathrm{Enc}\) kunci utama kumpulan kunci, sedangkan fungsi \(\mathrm{Dec}\) mencoba mendekripsi dengan semua kunci, dengan melalui kunci dalam urutan tertentu (lihat di bawah untuk mengetahui cara Tink meningkatkan performa ini).
Menarik untuk dicatat bahwa Keyset adalah kunci lengkap:
Keyset adalah deskripsi lengkap dari fungsi \(\mathrm{Enc}\) dan
\(\mathrm{Dec}\) yang digunakan. Artinya, pengguna dapat menulis class yang mengambil KeysetHandle sebagai
input, yang menyatakan bahwa class memerlukan deskripsi objek
lengkap \(\mathrm{Enc}\) dan \(\mathrm{Dec}\) agar berfungsi
dengan benar. Hal ini memungkinkan pengguna menulis API yang mengomunikasikan hal tersebut: untuk menggunakan
class ini, Anda perlu memberikan deskripsi primitif kriptografi kepada saya.
Rotasi kunci
Pertimbangkan pengguna Tink, yang menulis program yang pertama-tama mendapatkan set kunci dari KMS, lalu membuat objek AEAD dari set kunci ini, dan akhirnya menggunakan objek ini untuk mengenkripsi dan mendekripsi teks tersandi.
Pengguna tersebut otomatis disiapkan untuk rotasi kunci; dan algoritma pengalihan jika pilihan mereka saat ini tidak lagi memenuhi standar.
Namun, Anda harus berhati-hati saat menerapkan rotasi kunci tersebut: Pertama, KMS harus menambahkan kunci baru ke set kunci (tetapi belum menetapkannya sebagai kunci utama). Kemudian, keyset baru harus diluncurkan ke semua program biner, sehingga setiap program biner yang menggunakan keyset ini memiliki kunci terbaru dalam keyset. Baru setelah itu kunci baru harus dijadikan kunci utama, dan keyset yang dihasilkan didistribusikan lagi ke semua biner menggunakan keyset.
ID utama dalam teks tersandi
Pertimbangkan kembali contoh keyset AEAD. Jika dilakukan secara naif, mendekripsi teks tersandi 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 untuk memberi awalan pada ciphertext dengan string 5 byte yang berasal dari ID. Mengikuti filosofi 'Kunci Penuh' di atas, awalan ini adalah bagian dari kunci, dan semua ciphertext yang pernah diturunkan dengan 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.
Jika kunci ada dalam keyset, Tink akan menghitung tag ini dari ID yang dimiliki kunci dalam keyset. Fakta bahwa ID bersifat unik2 dalam set kunci menyiratkan bahwa tag bersifat unik. Oleh karena itu, jika hanya kunci yang diberi tag yang digunakan, tidak ada penurunan performa dibandingkan dengan mendekripsi menggunakan 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 set kunci jika memiliki satu ID tertentu. Hal ini memiliki beberapa implikasi saat mendeskripsikan penerapan objek utama dalam bahasa yang berbeda.
Kunci dengan persyaratan ID, tetapi tidak ada awalan output
Beberapa kunci harus memiliki ID tertentu, tetapi tidak menambahkan awalan ke outputnya. Misalnya, kunci tanda tangan dengan varian NO_PREFIX_WITH_PREHASH_ID (disimpan
dengan jenis awalan output WITH_ID_REQUIREMENT) menghasilkan tanda tangan tanpa
awalan. Saat Anda menggunakan kunci tersebut dengan primitif
Prehash, Tink
menulis ID kunci ke dalam nilai pra-hash, sehingga penanda tangan jarak jauh mengetahui kunci mana yang harus digunakan untuk menandatangani.
Seperti kunci yang menggunakan awalan, kunci tersebut hanya dapat berada dalam keyset dengan satu ID tersebut. ID kunci dalam nilai pra-hash adalah metadata biasa, seperti awalan output: tanda tangan tidak mengikatnya, dan verifikator tidak pernah melihatnya. Untuk tata letak tingkat byte, lihat Format melalui kabel Tink.
-
Beberapa bagian Tink masih memperlakukan Keyset sebagai set. Namun, hal ini harus diubah. Alasannya adalah karena urutan secara umum penting: misalnya, pertimbangkan siklus proses umum rotasi kunci dengan Aead. Pertama, kunci baru ditambahkan ke set 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 dijadikan kunci utama (hanya pada saat ini penggunaan kunci ini aman). Pada langkah kedua ini, rotasi kunci perlu mengetahui kunci terakhir yang ditambahkan. ↩
-
Untuk kompatibilitas dengan library internal Google, Tink memungkinkan adanya kumpulan kunci yang ID-nya berulang. Dukungan ini akan dihapus pada masa mendatang. ↩