Pembuat HMAC & pemeriksa tanda tangan

Menghitung HMAC-SHA-1, SHA-256, SHA-384, dan SHA-512 dari pesan dan kunci, serta mengenali dari mana sebuah tanda tangan berasal.

Pesan
HMAC-SHA-1
HMAC-SHA-256
HMAC-SHA-384
HMAC-SHA-512

Masukkan sebuah kunci untuk menghitung tanda tangan.

Apa yang dilakukan alat ini

HMAC mengubah sebuah pesan dan sebuah rahasia bersama menjadi sebuah tanda tangan pendek. Siapa pun yang memegang rahasia yang sama bisa menghitungnya ulang dan melihat apakah pesan tiba tanpa perubahan dan datang dari seseorang yang juga tahu rahasianya. Alat ini menghitung keempat varian umum sekaligus, dan — diberi sebuah tanda tangan yang dikirim kepada Anda — memberi tahu Anda yang mana yang menghasilkannya.

Arah kedua itu biasanya alasan orang datang. Sebuah webhook gagal verifikasi, dan pertanyaannya sebenarnya bukan "apakah tanda tangan ini valid" melainkan "yang mana dari beberapa hal masuk akal yang saya lakukan berbeda dari pengirim".

Kunci adalah tempat ini menjadi salah

HMAC menandatangani bita dengan bita. Pesannya biasanya jelas — badan permintaan mentah — tetapi kuncinya hampir tak pernah, karena sebuah rahasia tiba sebagai sebuah string dan sebuah string bukan bita sampai Anda memutuskan cara membacanya:

a3f2   as text     4 bytes   61 33 66 32
a3f2   as hex      2 bytes   a3 f2

Kedua pembacaan sah, keduanya menghasilkan tanda tangan yang sangat baik bentuknya, dan kedua tanda tangan tak punya kesamaan. Tak ada yang memperingatkan Anda: tak ada galat, tak ada keluhan panjang, hanya sebuah nilai yang tak cocok dengan yang dihitung pengirim. Itulah sebabnya pengodean kunci di sini adalah pilihan yang terlihat ketimbang tebakan — ketika sebuah tanda tangan tak cocok, ini adalah hal pertama yang dibalik.

Sebagai panduan kasar: sebuah rahasia dengan prefiks seperti whsec_ atau serangkaian huruf dan digit besar-kecil campur biasanya dimaksudkan sebagai teks; sebuah string persis 32 atau 64 karakter yang hanya memakai 0-9 dan a-f biasanya heksadesimal; dan yang diakhiri = hampir pasti Base64. Tetapi periksa dokumentasi pengirim ketimbang bentuknya, karena bentuk bukan bukti.

Pesan harus berupa bita persis

Separuh lain dari sebuah ketidakcocokan adalah pesannya. HMAC didefinisikan atas bita, jadi apa pun yang mengubah bita mengubah tanda tangan sepenuhnya — tak ada kredit sebagian dan tak ada nyaris meleset.

  • Menserialkan ulang JSON. Mengurai sebuah badan dan menstringkannya lagi bisa menata ulang kunci, mengubah spasi, atau menormalkan angka. Tandatangani dan verifikasi badan mentah yang Anda terima, tak pernah salinannya yang berpulang-pergi.
  • Sebuah baris-baru di ujung. Beberapa alat menambahkannya ketika Anda menyimpan badan ke sebuah berkas; ia adalah sebuah bita, dan ia mengubah segalanya.
  • Pengodean karakter. Sebuah badan yang mengandung teks non-ASCII harus dibaca sebagai pengodean yang sama yang dipakai kedua sisi — UTF-8 dalam praktik.
  • Kompresi atau middleware. Jika sesuatu di depan penangan Anda mendekompresi atau menulis ulang badan, verifikasi sebelum itu terjadi, bukan sesudah.

Banyak penyedia juga tak menandatangani badan saja. Stripe menandatangani sebuah stempel waktu dan badan yang digabung dengan sebuah titik; AWS menandatangani sebuah permintaan kanonis yang dibangun dari metode, path, header, dan sebuah hash dari payload. Jika verifikasi gagal terhadap badan polos, string yang ditandatangani mungkin bukan badan polos — itu didokumentasikan di sisi pengirim dan layak dibaca sebelum men-debug lebih jauh.

Mengapa SHA-1 ditawarkan di sini dan bukan di alat hash

Alat hash menandai SHA-1 sebagai rusak. Yang ini mendaftar HMAC-SHA-1 tanpa peringatan, dan itu disengaja ketimbang sebuah kelalaian.

SHA-1 tak terpakai untuk tanda tangan dan sertifikat karena tumbukan bisa dibangun: dua dokumen berbeda bisa dibuat berbagi sebuah digest. HMAC tak bergantung pada sifat itu. Keamanannya bertumpu pada kunci rahasia, dan konstruksinya — meng-hash pesan dua kali, dengan kunci tercampur kedua kalinya — bertahan bahkan ketika hash yang mendasarinya lemah-tumbukan. HMAC-SHA-1 tetap kukuh dan masih yang dipakai OAuth 1.0a dan penandatanganan AWS lama, jadi sebuah alat yang menolak menghitungnya cukup menjadi kurang berguna tanpa menjadi lebih aman.

Untuk apa pun yang baru, SHA-256 adalah default yang masuk akal. Digest lebih panjang tak lebih kuat secara berarti di sini — plafon keamanan adalah kuncinya, bukan panjang digest — jadi SHA-384 dan SHA-512 layak dipilih hanya ketika sesuatu yang harus Anda saling-operasikan memintanya.

Membandingkan tanda tangan dengan aman

Halaman ini membandingkan dengan perbandingan string biasa, yang tak apa di sini: Anda memegang kuncinya sendiri, jadi tak ada yang bisa bocor. Dalam sebuah server yang memverifikasi permintaan masuk, itu tak apa. Sebuah perbandingan biasa berhenti pada bita berbeda pertama, jadi waktu yang dibutuhkannya mengungkap seberapa banyak sebuah tebakan yang benar, dan seorang penyerang yang bisa mengirim banyak permintaan bisa memulihkan sebuah tanda tangan valid satu bita pada satu waktu.

Pakai perbandingan waktu-konstan yang disediakan platform Anda — crypto.timingSafeEqual di Node, hmac.compare_digest di Python, hash_equals di PHP — pada bita mentah ketimbang pada string heksadesimal. Bersamanya, bandingkan terhadap sebuah tanda tangan yang Anda hitung sendiri ketimbang memercayai sebuah algoritme yang dinamai dalam permintaan, dan tolak sebuah pesan yang stempel waktunya jauh dari sekarang sehingga sebuah tanda tangan valid lama tak bisa diputar ulang.

HMAC bukan sebuah hash, dan bukan sebuah tanda tangan

Tiga hal terkelirukan di sini, dan perbedaannya penting untuk apa yang bisa Anda klaim sesudahnya:

  • Sebuah hash mengambil sebuah pesan dan menghasilkan sebuah digest. Siapa pun bisa menghitungnya, jadi ia membuktikan pesan tak berubah secara tak sengaja — bukan bahwa ia datang dari siapa pun secara khusus.
  • Sebuah HMAC mengambil sebuah pesan dan sebuah rahasia bersama. Kedua pihak memegang kunci yang sama, jadi ia membuktikan pengirim tahu rahasianya. Ia tak bisa membuktikan pihak mana yang mengirimnya, karena keduanya bisa saja menghasilkannya.
  • Sebuah tanda tangan memakai sebuah kunci privat yang hanya dipegang pengirim, dan sebuah kunci publik yang siapa pun bisa memverifikasinya. Itulah yang memberi nirsangkal: pengirim tak bisa kemudian menyangkalnya.

Jadi HMAC adalah alat yang tepat di antara dua sistem yang sudah berbagi sebuah rahasia — webhook, API internal, token sesi — dan yang salah ketika Anda perlu membuktikan kepada pihak ketiga siapa yang mengirim sesuatu. Perhatikan pula ia mengautentikasi tetapi tak menyembunyikan: pesan berkelana terbuka, dan HMAC tak mengatakan apa pun tentang kerahasiaan.

Pertanyaan yang sering diajukan

Tanda tangan saya tak cocok. Apa yang saya periksa dulu?
Pengodean kunci, lalu bita pesan. Sebuah rahasia yang tampak seperti heksadesimal sering dimaksudkan sebagai heksadesimal ketimbang teks, dan keduanya menghasilkan tanda tangan yang sepenuhnya berbeda tanpa galat dengan cara apa pun. Setelah itu, pastikan Anda menandatangani badan mentah persis seperti diterima ketimbang salinannya yang diserialkan ulang.
Mengapa SHA-1 ditawarkan di sini padahal alat hash mengatakan ia rusak?
Karena HMAC tak mengandalkan ketahanan tumbukan, yang menjadi sifat yang hilang dari SHA-1. Keamanannya datang dari kunci. HMAC-SHA-1 masih kukuh dan masih dipakai OAuth 1.0a dan penandatanganan AWS lama, meski SHA-256 adalah default yang tepat untuk apa pun yang baru.
Apakah digest lebih panjang lebih aman?
Tak secara berarti. Kekuatan sebuah HMAC dibatasi rahasianya, bukan panjang digest, jadi SHA-512 tak empat kali lebih baik daripada SHA-256. Pilih yang diharapkan sisi lain.
Apa perbedaan antara HMAC dan tanda tangan digital?
HMAC memakai satu rahasia yang kedua sisi tahu, jadi ia membuktikan pengirim tahu rahasianya tetapi bukan sisi mana yang mengirimnya. Sebuah tanda tangan digital memakai sebuah kunci privat yang hanya dipegang pengirim, jadi pihak ketiga bisa memverifikasinya dan pengirim tak bisa menyangkalnya. Jika Anda butuh sifat terakhir itu, HMAC adalah alat yang salah.
Apakah saya sebaiknya membandingkan tanda tangan dengan ===?
Tidak di sebuah server. Sebuah perbandingan biasa kembali begitu bita berbeda, dan pewaktuan itu membocorkan seberapa banyak sebuah tanda tangan yang ditebak benar. Pakai perbandingan waktu-konstan platform Anda pada bita mentah. Pada halaman ini itu tak penting, karena Anda sudah memegang kuncinya.
Apakah kunci saya dikirim ke mana pun?
Tidak. Semuanya dihitung di browser Anda dengan Web Crypto API; pesan dan kunci tak pernah meninggalkan perangkat Anda.