Petunjuk dan konteks
Layanan konfigurasi multi-tenant harus mengenkripsi nilai database yang sensitif. Setiap tenant memiliki kunci logis independen; platform harus merotasi root key, membaca ciphertext lama, dan mendeteksi ciphertext yang disalin antar tenant atau rekaman. Gunakan crypto/hpke Go 1.26 untuk merancang amplop, alur enkripsi/dekripsi, versi kunci, pengikatan konteks, dan migrasi. Keahlian intinya adalah komposisi API kriptografi yang benar dan perancangan siklus hidup, jadi ini adalah pertanyaan coding.
Apa yang dievaluasi pewawancara
Pertama, apakah Anda memahami peran HPKE KEM, KDF, dan AEAD serta membedakan enkapsulasi kunci publik dari enkripsi data simetris.
Kedua, apakah Anda dapat memilih mode Base, PSK, atau Auth dan menjelaskan batas antara kunci autentikasi dan kunci kerahasiaan.
Ketiga, apakah tenant, tujuan (purpose), suite, dan versi terikat dalam info atau AAD untuk mencegah dekripsi lintas konteks.
Keempat, apakah rotasi, pembacaan versi lama, pencabutan (revocation), dan enkripsi ulang dirancang tanpa memperlakukan nomor versi sebagai rahasia.
Kelima, apakah pengujian perusakan (tamper), replay, keacakan, informasi kegagalan, dan interoperabilitas memvalidasi implementasi tersebut.
Pertanyaan untuk diklarifikasi terlebih dahulu
- Apakah kerahasiaan saja sudah cukup, atau pengirim harus diautentikasi secara kriptografis?
- Siapa yang memiliki kunci publik penerima, dan apakah terdapat persyaratan KMS, HSM, serta audit?
- Berapa lama ciphertext lama bertahan, dan apakah enkripsi ulang di latar belakang diperlukan?
- Apakah hubungan tenant dan kunci konfigurasi diizinkan menjadi metadata yang terlihat?
- Apakah dekripsi lintas bahasa atau pemulihan offline diperlukan?
- Haruskah kunci yang hilang, versi yang tidak didukung, dan kegagalan autentikasi dapat dibedakan?
Jawaban 30 detik
“Saya menetapkan suite RFC 9180 dan Go 1.26. Layanan menyimpan kunci privat penerima untuk setiap tenant, sementara aplikasi mengenkapsulasi dengan kunci publiknya. Amplop menyimpan suite dan versi kunci; tenant dan tujuan diikat dalam info serta tenant, kunci, dan versi rekaman dalam AEAD AAD. Dekripsi memilih kunci privat lama berdasarkan versi amplop. Penulisan baru menggunakan versi yang telah dirotasi dan tugas latar belakang mengenkripsi ulang data lama. Saya memilih Auth hanya jika bukti pengirim diperlukan. Pengujian mencakup perusakan, pertukaran lintas tenant, replay, keacakan, versi lama, dan vektor lintas bahasa.”
Solusi mendalam
Langkah 1: Pisahkan lapisan amplop
HPKE membuat shared secret dengan KEM, menurunkan kunci dengan KDF, dan mengenkripsi pesan dengan AEAD. Amplop menyimpan suite, versi kunci, material terenkapsulasi, nonce atau ciphertext yang diserialisasi, dan metadata publik. Kunci root dan privat penerima tetap berada di KMS atau HSM, tidak pernah di dalam ciphertext atau log aplikasi.
Langkah 2: Pilih mode dan semantik identitas
Mode Base memberikan enkripsi kunci publik penerima tanpa autentikasi pengirim. PSK menambahkan pre-shared key. Auth menggunakan kunci pengirim untuk mengautentikasi sumber. Identitas login platform bukan berarti HPKE telah mengautentikasi pengirim; otorisasi dan mode kriptografi adalah lapisan yang terpisah.
Langkah 3: Ikat konteks
Ikat protokol, layanan, versi, dan tujuan dalam info. Ikat ID tenant, kunci konfigurasi, dan versi rekaman dalam AEAD AAD ketika bidang tersebut dikirim bersama amplop dan harus tetap utuh. Dekripsi menghitung ulang input yang sama, sehingga pertukaran tenant, tujuan, atau versi akan gagal dalam autentikasi.
envelope = suite_id | key_version | encapsulated_key | aad_fields | ciphertext
info = "config-envelope/v1" | tenant_scope | purpose
aad = tenant_id | config_key | record_versionLangkah 4: Rancang siklus hidup kunci
Setiap versi kunci memiliki waktu pembuatan, status, cakupan dekripsi, dan kebijakan penghancuran. Publikasikan kunci publik baru sebelum beralih untuk operasi penulisan; operasi pembacaan memilih kunci privat lama berdasarkan versi amplop. Pertahankan versi lama sebagai read-only sampai enkripsi ulang dan pemeriksaan audit selesai, kemudian cabut kunci tersebut.
Langkah 5: Tangani replay dan serialisasi
AEAD mendeteksi perusakan data tetapi tidak menghentikan ciphertext lama yang valid untuk dikirimkan kembali. Jika konfigurasi memiliki versi atau urutan monotonik, lapisan bisnis akan memeriksa versi yang diharapkan. Gunakan bidang panjang, versi, dan suite yang eksplisit serta tolak suite yang tidak dikenal, pemotongan data (truncation), atau bidang duplikat.
Langkah 6: Tentukan batas kesalahan (error boundary)
Secara eksternal, kembalikan kegagalan dekripsi yang seragam. Secara internal, audit alasan terstruktur dan versi kunci, jangan pernah mencatat kunci privat, plaintext, atau ciphertext lengkap. Membedakan kunci yang hilang, format yang tidak didukung, dan kegagalan autentikasi membantu operasi, tetapi pemanggil yang tidak tepercaya tidak boleh mengetahui keberadaan tenant atau kunci dari waktu respon atau pesan kesalahan.
Langkah 7: Bangun pengujian dan migrasi
Uji vektor RFC tetap, keacakan, perusakan satu byte, AAD lintas tenant, pembacaan versi lama, rotasi konkuren, kegagalan pasca-pencabutan, dan pemotongan pesan besar (chunking). Sistem lintas bahasa memerlukan serialisasi dan vektor bersama. Layanan pra-1.26 menggunakan wrapper kompatibilitas atau gerbang peningkatan; API eksperimental tidak boleh masuk ke lingkungan produksi secara tidak sengaja.
Contoh jawaban berkualitas tinggi
“Saya menggunakan HPKE sebagai lapisan amplop: KEM dan KDF membuat serta menurunkan shared key, dan AEAD melindungi plaintext konfigurasi. Amplop berisi suite, versi kunci, material terenkapsulasi, dan ciphertext; tenant, tujuan, kunci, dan versi rekaman diikat melalui info dan AAD untuk menghentikan penyalinan lintas tenant. Base hanya memberikan kerahasiaan penerima; saya memilih Auth atau tanda tangan luar saat bukti pengirim diperlukan. Rotasi menulis versi baru terlebih dahulu, menjaga versi lama sebagai read-only, mengenkripsi ulang di latar belakang, lalu mencabutnya setelah verifikasi. AEAD tidak mencegah replay, jadi versi bisnis diperiksa. Kunci privat tetap berada di KMS/HSM, dan pengujian mencakup perusakan data, pencabutan, kesalahan, dan vektor lintas bahasa.”
Kesalahan umum
- Memperlakukan Base sebagai autentikasi pengirim → penerima tidak dapat membuktikan siapa yang mengirimkannya → gunakan Auth atau tanda tangan luar.
- Menempatkan tenant hanya di metadata yang terlihat → penyerang dapat menukar ciphertext antar tenant → ikat dalam
infoatau AAD. - Menghapus kunci lama segera setelah rotasi → data historis menjadi tidak dapat dibaca → pertahankan jendela read-only dan lakukan enkripsi ulang terlebih dahulu.
- Mengasumsikan AEAD mencegah replay → ciphertext lama yang valid dapat dikirimkan kembali → periksa versi bisnis atau urutan.
- Menyimpan kunci privat di konfigurasi atau log → batas enkripsi rusak → gunakan KMS/HSM dan prinsip hak akses terendah (least privilege).
- Membuat format biner tanpa versi → migrasi dan penolakan suite menjadi tidak aman → enkode versi, panjang, dan suite secara eksplisit.
- Mengembalikan kesalahan dekripsi yang detail → keberadaan tenant atau kunci dapat bocor → gunakan kesalahan eksternal yang seragam dan audit internal.
- Hanya menguji skenario sukses → kegagalan perusakan data dan versi lama akan lolos ke produksi → tambahkan uji vektor, lintas konteks, dan pencabutan.
Pertanyaan lanjutan
Lanjutan 1: Mengapa tidak mengenkripsi semua plaintext langsung dengan RSA atau ECDH?
HPKE secara eksplisit menyusun KEM, KDF, dan AEAD, yang cocok untuk mengenkapsulasi kunci sesi simetris dan menangani pesan berukuran besar. Enkripsi kunci publik langsung pada plaintext arbitrer mengundang penyalahgunaan panjang, keacakan, dan mode.
Lanjutan 2: Kapan mode Auth tepat digunakan?
Gunakan Auth ketika penerima membutuhkan bukti kriptografis bahwa kunci pengirim yang diketahui ikut berpartisipasi. Jika hanya kerahasiaan penerima yang diperlukan, jangan menambahkan kunci autentikasi yang tidak dikelola.
Lanjutan 3: Apa perbedaan antara info dan AAD?
info berpartisipasi dalam penurunan kunci dan mendefinisikan konteks protokol. AAD tetap terlihat tetapi integritasnya dilindungi oleh AEAD, menjadikannya cocok untuk metadata amplop yang harus cocok selama dekripsi.
Lanjutan 4: Bagaimana cara mengenkripsi ulang dengan aman?
Baca versi lama dan tulis versi baru dalam transaksi idempoten atau alur kerja yang dapat dicoba ulang (retryable). Hanya cabut kunci lama setelah ciphertext baru lolos verifikasi decrypt-and-read-back dan pemeriksaan audit.
Lanjutan 5: Bagaimana cara menghentikan ciphertext agar tidak dipindahkan ke rekaman lain?
Tempatkan tenant, kunci konfigurasi, versi rekaman, dan tujuan di AAD, lalu bangun kembali AAD dari nilai database saat ini selama pembacaan. Amplop yang disalin kemudian akan gagal dalam pemeriksaan tag autentikasinya.
Lanjutan 6: Apakah HPKE menyediakan forward secrecy?
Karakteristik ini tergantung pada siklus hidup kunci dan mode. Dengan kunci privat penerima statis yang berumur panjang, perlindungan ciphertext historis bergantung pada kunci tersebut. Forward secrecy yang lebih kuat membutuhkan kunci efemeral, rotasi, pemusnahan, dan sesi tingkat protokol; nama API saja tidak menyediakannya secara otomatis.