Primitif Prehash dan SignPrehash membagi komputasi tanda tangan digital menjadi dua langkah:
- Prehash hanya memerlukan kunci publik. Fungsi ini mengubah pesan dengan panjang arbitrer menjadi nilai pra-hash berukuran tetap yang pendek.
- SignPrehash memerlukan kunci pribadi. Mengubah nilai pra-hash menjadi tanda tangan.
Tanda tangan yang dihasilkan adalah tanda tangan biasa pada pesan asli. Anda memverifikasinya dengan primitif
Tanda Tangan Digital PublicKeyVerify biasa, dan
pemverifikasi tidak perlu mengetahui -- atau peduli -- bahwa tanda tangan dibuat dalam
dua langkah.
Perlakukan nilai pra-hash sebagai byte buram. Objek ini memiliki ukuran tetap dan membawa ID kunci yang dihitungnya, tetapi tata letaknya adalah bagian dari format wire Tink, dan Anda tidak boleh mengurai atau membuat objek ini sendiri. Jika Anda mentransfer Tink atau memerlukan detail tingkat byte, lihat format wire Tink.
Gunakan pasangan primitif ini saat:
- Kunci penandatanganan berada di tempat lain, misalnya di HSM, di KMS, atau di belakang batas RPC, dan Anda tidak ingin mengirim pesan lengkap melintasi batas tersebut.
- Pesan berukuran besar, dan penanda tangan jarak jauh menerapkan batas ukuran permintaan.
Jika tidak ada yang berlaku, gunakan primitif Tanda Tangan Digital biasa: lebih sederhana, dan lebih sulit disalahgunakan.
Keyset
Kedua primitif memilih kunci secara berbeda, dengan cara yang sama seperti yang dilakukan penandatanganan dan verifikasi untuk primitif Tanda Tangan Digital:
Prehash.Computeselalu menggunakan kunci utama dari set kunci publik, dan mencatat ID kunci tersebut dalam nilai pra-hash. Sisi inilah yang memilih kunci mana yang akan digunakan untuk membuat tanda tangan.SignPrehash.Signmembaca ID kunci dari nilai pra-hash dan menandatangani dengan kunci yang diaktifkan yang cocok dari set kunci pribadi. Sisi ini adalah sisi yang mengikuti pilihan yang telah dibuat orang lain. Jika tidak ada kunci yang diaktifkan dalam keyset yang memiliki ID tersebut, panggilan akan gagal.
Setiap kunci dalam set kunci SignPrehash harus memiliki persyaratan ID, jika tidak, pembuatan primitif akan gagal.
Jaminan keamanan minimal
- Tanda tangan yang dihasilkan memiliki properti yang sama dengan tanda tangan yang dihasilkan oleh primitif Tanda Tangan Digital dengan jenis kunci yang sama.
- Tink menambahkan awalan pada nilai pra-hash dengan 5 byte yang berisi nilai khusus yang dicadangkan dan ID kunci yang digunakan untuk menghitungnya.
SignPrehashmenandatangani nilai hanya dengan kunci tersebut. Apakah nilai terikat secara kriptografis ke kunci tersebut bergantung pada algoritma; untuk ML-DSA Mu Eksternal, nilai terikat secara kriptografis, lihat format kabel Tink. - Pesan dapat memiliki panjang yang bervariasi.
Hal yang perlu diperhatikan
- Penandatangan tidak dapat memeriksa apa yang ditandatanganinya. Siapa pun yang dapat memanggil
SignPrehashdapat menandatangani pesan arbitrer, dan penandatangan tidak dapat menerapkan kebijakan ke isi pesan. Lindungi akses keSignPrehashpersis seperti Anda melindungi akses kePublicKeySign. - Lindungi nilai pra-hash dalam pengiriman. Kunci ini tidak rahasia, tetapi penyerang yang dapat mengubahnya saat dalam perjalanan mengontrol apa yang ditandatangani.
Pilih jenis kunci
ML-DSA dalam mode External Mu, seperti yang dijelaskan dalam RFC 9881, adalah satu-satunya algoritma yang didukung Tink untuk Prehash dan SignPrehash. Anda harus menggunakan kunci ML-DSA standar dengan primitif ini.
Sebaiknya gunakan ML_DSA_65 untuk sebagian besar kasus penggunaan.
Kunci harus memiliki persyaratan ID, karena setiap nilai pra-hash dimulai dengan awalan yang berisi ID kunci yang dihitung. Varian berikut diterima:
TINK-- tanda tangan yang dihasilkan dimulai dengan awalan output 5 byte biasa Tink.NO_PREFIX_WITH_PREHASH_ID-- tanda tangan yang dihasilkan tidak memiliki awalan output, sementara kunci masih memiliki ID yang diperlukan nilai pra-hash.
Kunci yang menggunakan varian NO_PREFIX (mentah) tidak didukung, karena
tidak memiliki ID kunci.
Contoh
Contoh berikut menandatangani pesan dalam dua langkah, lalu memverifikasi tanda tangan yang dihasilkan dengan primitif Tanda Tangan Digital biasa.
Keduanya ditampilkan sebagai satu blok agar mudah dibaca. Dalam deployment yang sebenarnya, kedua langkah tersebut berjalan di tempat yang berbeda; lihat Saya ingin menandatangani data dengan penanda tangan jarak jauh untuk mengetahui panduan langkah demi langkah.
C++
#include "tink/keyset_handle.h" #include "tink/public_key_verify.h" #include "tink/signature/config_2026.h" #include "tink/signature/prehash.h" #include "tink/signature/sign_prehash.h" using ::crypto::tink::ConfigSignature2026; using ::crypto::tink::Prehash; using ::crypto::tink::PublicKeyVerify; using ::crypto::tink::SignPrehash; // 1. Wherever the message is: compute the prehash value. This needs only // the public keyset. absl::StatusOr<std::unique_ptr<Prehash>> prehasher = public_handle.GetPrimitive<Prehash>(ConfigSignature2026()); if (!prehasher.ok()) return prehasher.status(); absl::StatusOr<std::string> prehash = (*prehasher)->Compute(message); if (!prehash.ok()) return prehash.status(); // 2. Wherever the private key is: turn the prehash value into a signature. absl::StatusOr<std::unique_ptr<SignPrehash>> signer = private_handle.GetPrimitive<SignPrehash>(ConfigSignature2026()); if (!signer.ok()) return signer.status(); absl::StatusOr<std::string> signature = (*signer)->Sign(*prehash); if (!signature.ok()) return signature.status(); // 3. Anywhere: verify the signature over the original message. absl::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier = public_handle.GetPrimitive<PublicKeyVerify>(ConfigSignature2026()); if (!verifier.ok()) return verifier.status(); absl::Status verified = (*verifier)->Verify(*signature, message);
Go
import ( "github.com/tink-crypto/tink-go/v2/signature" "github.com/tink-crypto/tink-go/v2/signprehash" ) // 1. Wherever the message is: compute the prehash value. This needs only // the public keyset. prehasher, err := signprehash.NewPrehash(publicHandle) if err != nil { return err } prehash, err := prehasher.ComputePrehash(message) if err != nil { return err } // 2. Wherever the private key is: turn the prehash value into a signature. signer, err := signprehash.NewPrehashSigner(privateHandle) if err != nil { return err } sig, err := signer.SignPrehash(prehash) if err != nil { return err } // 3. Anywhere: verify the signature over the original message. verifier, err := signature.NewVerifier(publicHandle) if err != nil { return err } if err := verifier.Verify(sig, message); err != nil { return err }
Topik terkait
- Saya ingin menandatangani data dengan penanda tangan jarak jauh -- panduan langkah demi langkah untuk alur dua langkah.
- Tanda tangan digital -- menandatangani dan memverifikasi dalam satu langkah, saat penanda tangan dapat melihat pesan.
- Jenis kunci primitif yang didukung menurut bahasa
- Format kabel Tink -- tata letak tingkat byte dari nilai pra-hash, untuk memindahkan Tink ke bahasa lain.