Pembuat HMAC
Menghitung HMAC-SHA-1, SHA-256, SHA-384, dan SHA-512 dari pesan dan kunci, serta mengenali dari mana tanda tangan berasal.
Masukkan kunci untuk menghitung tanda tangan.
Apa yang dilakukan alat ini
HMAC mengubah pesan dan rahasia bersama menjadi 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 tanda tangan yang dikirim kepada Anda — memberi tahu Anda yang mana yang menghasilkannya.
Arah kedua itu biasanya alasan orang datang. 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". Prefiks bergaya sha256= di depan tanda tangan yang ditempel dikenali dan dibuang, sehingga nilai header webhook bisa ditempel persis seperti saat tiba.
Kunci adalah tempat hal ini menjadi salah
HMAC menandatangani bita dengan bita. Pesannya biasanya jelas — badan permintaan mentah — tetapi kuncinya hampir tak pernah demikian, karena rahasia tiba sebagai string dan 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 soal panjang, hanya nilai yang tak cocok dengan yang dihitung pengirim. Itulah sebabnya pengodean kunci di sini adalah pilihan eksplisit ketimbang tebakan — ketika tanda tangan tak cocok, ini adalah hal pertama yang dibalik.
Sebagai panduan kasar: rahasia dengan prefiks seperti whsec_ atau serangkaian huruf dan digit besar-kecil campur biasanya dimaksudkan sebagai teks; 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 ketidakcocokan adalah pesannya. HMAC didefinisikan atas bita, jadi apa pun yang mengubah bita mengubah tanda tangan sepenuhnya — tak ada nilai sebagian dan tak ada yang nyaris cocok.
- Menyerialkan ulang JSON. Mengurai 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.
- Baris-baru di ujung. Beberapa alat menambahkannya ketika Anda menyimpan badan ke berkas; ia adalah satu bita, dan ia mengubah segalanya.
- Pengodean karakter. 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 stempel waktu dan badan yang digabung dengan titik; AWS menandatangani permintaan kanonis yang dibangun dari metode, path, header, dan 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 kelalaian.
SHA-1 tak bisa dipakai untuk tanda tangan dan sertifikat karena tumbukan bisa dibangun: dua dokumen berbeda bisa dibuat berbagi digest. HMAC tak bergantung pada sifat itu. Keamanannya bertumpu pada kunci rahasia, dan konstruksinya — meng-hash pesan dua kali, dengan kunci ikut tercampur pada keduanya — 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 alat yang menolak menghitungnya hanya akan 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 bekerja sama dengan Anda 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 server yang memverifikasi permintaan masuk, itu tidak baik. Perbandingan biasa berhenti pada bita berbeda pertama, jadi waktu yang dibutuhkannya mengungkap seberapa banyak bagian dari tebakan itu yang benar, dan seorang penyerang yang bisa mengirim banyak permintaan bisa memulihkan 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. Di samping itu, bandingkan terhadap tanda tangan yang Anda hitung sendiri ketimbang memercayai algoritme yang dinamai dalam permintaan, dan tolak pesan yang stempel waktunya jauh dari sekarang sehingga tanda tangan valid lama tak bisa diputar ulang.
HMAC bukan hash, dan bukan tanda tangan
Tiga hal kerap tertukar di sini, dan perbedaannya penting untuk apa yang bisa Anda klaim sesudahnya:
- Hash mengambil pesan dan menghasilkan digest. Siapa pun bisa menghitungnya, jadi ia membuktikan pesan tak berubah secara tak sengaja — bukan bahwa ia datang dari siapa pun secara khusus.
- HMAC mengambil pesan dan 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.
- Tanda tangan memakai kunci privat yang hanya dipegang pengirim, dan kunci publik yang bisa dipakai siapa pun untuk memverifikasi. Itulah yang memberi nirsangkal: pengirim tak bisa kemudian menyangkalnya.
Jadi HMAC adalah alat yang tepat di antara dua sistem yang sudah berbagi 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 melintas terbuka, dan HMAC tak mengatakan apa pun tentang kerahasiaan.
Memverifikasi tanda tangan webhook Stripe
Stripe adalah satu-satunya resep di sini yang bukan sekadar tempel, dan biasanya justru yang sudah dicoba orang sebelum datang. Header Stripe-Signature adalah daftar elemen yang dipisahkan koma, bukan tanda tangan, dan string yang ditandatangani Stripe bukan badan permintaan saja. Yang memecah header menjadi beberapa baris adalah dokumentasi Stripe sendiri, demi keterbacaan; header sungguhan tiba dalam satu baris.
Stripe-Signature: t=1492774577, v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd, v0=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39
- Pesan: nilai t=, lalu titik, lalu badan permintaan mentah persis seperti saat tiba. Untuk header di atas, string itu dimulai dengan 1492774577. dan badan mengikuti persis sesudahnya. Stripe menyebutnya payload yang ditandatangani, dan di situlah seluruh alasan tanda tangan Stripe tak pernah cocok dengan badan saja.
- Kunci: rahasia penandatanganan milik endpoint itu saja, utuh, termasuk prefiks whsec_ miliknya. Ini bukan kunci API Anda, dan bukan rahasia endpoint lain — URL yang sama, didaftarkan dua kali, punya dua rahasia.
- Pengodean kunci: Teks. Rahasia penandatanganan adalah string yang dipilih Stripe dan, meski tampak acak, ia bukan heksadesimal maupun Base64; membacanya sebagai salah satunya memberi bita lain dan tanda tangan yang tak cocok dengan apa pun.
- Tanda tangan untuk dicek: hanya elemen v1, bukan seluruh header. v1= bisa ditempel apa adanya, karena label itu dibuang persis seperti sha256= — tetapi header lengkap tidak bisa, karena t= di depannya dianggap label dan yang menyusul sesudahnya bukan tanda tangan sama sekali.
Tiga hal lain tentang header ini layak diketahui sebelum Anda mengorek yang lain. Abaikan setiap skema yang bukan v1: elemen v0 pada peristiwa uji memang sengaja bukan tanda tangan sungguhan, dan mengabaikan sisanya justru yang mencegah skema yang lebih lemah dipaksakan kepada Anda. Selagi rahasia endpoint diputar, keduanya tetap berlaku hingga satu hari dan header membawa satu elemen v1 per rahasia, yang hanya satu di antaranya akan cocok. Dan setiap upaya pengiriman ditandatangani ulang, jadi upaya berikutnya tak membawa tanda tangan yang pertama — stempel waktu di dalam string yang ditandatangani juga yang membuat penolakan tanda tangan lama menjadi pertahanan sungguhan alih-alih isyarat, karena ia tak bisa diubah tanpa merusak tanda tangan.
Memverifikasi tanda tangan webhook GitHub
GitHub adalah tempel yang menjadi dasar pembuatan alat ini, dan satu-satunya resep di sini yang bisa Anda periksa dari ujung ke ujung, karena GitHub menerbitkan contoh yang sudah dihitung. Tanda tangan tiba di header X-Hub-Signature-256 sebagai label sha256= diikuti digest heksadesimal, dan label itu dikenali serta dibuang di sini, sehingga nilai header masuk persis seperti saat tiba.
X-Hub-Signature-256: sha256=757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17
- Pesan: badan permintaan mentah, bita demi bita. Contoh yang diterbitkan GitHub menandatangani badan Hello, World! dan tak ada apa pun sesudahnya — tanpa baris-baru di ujung.
- Kunci: rahasia yang Anda ketikkan di pengaturan webhook, persis seperti Anda mengetikkannya. Contoh yang diterbitkan memakai It's a Secret to Everybody.
- Pengodean kunci: Teks. Rahasia GitHub adalah string yang Anda pilih sendiri, jadi ia tak pernah heksadesimal — bahkan rahasia yang seluruhnya berisi digit heksadesimal dibaca sebagai karakter yang Anda ketikkan.
- Tanda tangan untuk dicek: seluruh nilai header, termasuk sha256=. Heksadesimal dibandingkan tanpa memandang huruf besar-kecil, jadi tak masalah dalam bentuk mana log Anda mencetaknya.
Ketiga nilai itu bersama-sama adalah pemeriksaan kewajaran tercepat yang ada: tempelkan dan halaman ini melaporkan kecocokan pada HMAC-SHA-256 dalam heksadesimal, yang memberi tahu Anda bahwa kalkulatornya dan cara Anda membaca resepnya sama-sama benar sebelum mencoba keduanya pada pengiriman sungguhan. GitHub juga mengirim header yang lebih lama, X-Hub-Signature, yang berupa HMAC-SHA-1 atas badan yang sama dan dipertahankan hanya demi kompatibilitas warisan; karena halaman ini menghitung keempat digest sekaligus, tanda tangan dari header mana pun di antara keduanya dikenali tanpa Anda perlu menyebutkan dari yang mana. Satu hal yang tak bisa diselamatkannya adalah badan yang tiba sebagai apa pun selain bita yang dikirim GitHub — payload bisa membawa karakter di luar ASCII, dan kedua sisi harus membacanya sebagai UTF-8.
Memverifikasi tanda tangan webhook Shopify
Shopify menulis digest-nya dalam Base64 dan bukan heksadesimal, dan itulah satu-satunya perbedaan yang penting di sini: 32 bita yang sama menjadi 44 karakter yang berakhir dengan satu tanda sama dengan, dan karakter itu adalah pengisi dan bukan label, jadi tak ada yang dipotong dari depannya.
X-Shopify-Hmac-SHA256: dXEH6g6yUJ/CESIczphLijdXC211hsIsRvQ3nIsEPhc=
- Pesan: badan permintaan mentah, bita demi bita seperti saat dikirimkan. Peringatan Shopify sendiri adalah soal middleware yang mengurai badan — verifikasi dulu dan urai sesudahnya, karena pengurai yang sudah mengubah badan menjadi objek telah membuang bitanya.
- Kunci: rahasia klien milik aplikasi tempat webhook itu bernaung. Bukan token aksesnya, dan bukan kunci API yang duduk di sebelahnya pada panel yang sama.
- Pengodean kunci: Teks. Seperti pada dua yang lain, rahasianya adalah string dan bukan pengodean bita.
- Tanda tangan untuk dicek: seluruh nilai header. Ia ditempel apa adanya dan, karena heksadesimal maupun Base64 dicoba terhadap setiap digest, pengodean yang dilaporkan halaman ini itu sendirilah jawaban atas ejaan mana yang dipakai pengirim.
Nilai pada blok di atas ada di sana untuk menunjukkan bentuknya: itu 32 bita yang sama seperti pada contoh GitHub, ditulis dalam Base64 alih-alih heksadesimal. Keduanya layak dilihat bersebelahan, karena itulah seluruh isi perbedaan antara kedua header — satu digest, dua ejaan — dan itu pula sebabnya halaman ini menyebutkan pengodean di samping algoritmenya alih-alih hanya memberi tahu Anda bahwa ada sesuatu yang cocok.
Pertanyaan yang sering diajukan
- Tanda tangan saya tak cocok. Apa yang saya periksa dulu?
- Pengodean kunci, lalu bita pesan. Rahasia yang tampak seperti heksadesimal sering dimaksudkan sebagai heksadesimal ketimbang teks, dan keduanya menghasilkan tanda tangan yang sepenuhnya berbeda tanpa galat dalam kasus mana 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 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. Tanda tangan digital memakai 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 server. Perbandingan biasa kembali begitu bita berbeda, dan pewaktuan itu membocorkan seberapa banyak bagian dari tanda tangan yang ditebak itu yang 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 peramban Anda dengan Web Crypto API; pesan dan kunci tak pernah meninggalkan perangkat Anda.
- Bagaimana cara memverifikasi tanda tangan webhook Stripe?
- Gabungkan tiga hal menjadi satu string — stempel waktu dari elemen t= pada header, titik, dan badan permintaan mentah — lalu tandatangani string itu dengan rahasia penandatanganan endpoint yang dibaca sebagai teks, kemudian bandingkan hasilnya dengan elemen v1 pada header. Bagian di atas menelusurinya bidang demi bidang. Yang menjatuhkan hampir semua orang adalah langkah pertama: badan saja bukan yang ditandatangani Stripe.
- Bagaimana cara memverifikasi tanda tangan webhook GitHub?
- Tandatangani badan permintaan mentah dengan rahasia webhook yang dibaca sebagai teks, memakai SHA-256, dan bandingkan digest heksadesimalnya dengan header X-Hub-Signature-256. Label sha256= boleh tetap ada ketika Anda menempelkannya di sini. GitHub menerbitkan contoh yang sudah dihitung — badan Hello, World! dengan rahasia It's a Secret to Everybody — dan itu cara tercepat memeriksa cara Anda membaca resepnya sebelum mencobanya pada pengiriman sungguhan.
- Bagaimana cara memverifikasi tanda tangan webhook Shopify?
- Tandatangani badan permintaan mentah dengan rahasia klien milik aplikasi tempat webhook itu bernaung, dibaca sebagai teks, memakai SHA-256, dan bandingkan digest Base64-nya dengan header X-Shopify-Hmac-SHA256. Seluruh nilai header ditempel apa adanya — tanda sama dengan di ujung adalah pengisi Base64. Ketika tak cocok, penyebab yang biasa adalah middleware yang mengurai badan sebelum penangan Anda melihatnya.
- Bagaimana cara memverifikasi tanda tangan webhook dari penyedia lain mana pun?
- Empat pertanyaan menuntaskannya, dan dokumentasi pengirim memuat keempatnya: header mana yang membawa tanda tangan, string mana yang sebenarnya ditandatangani, bagaimana rahasianya semestinya dibaca, dan apakah digest-nya heksadesimal atau Base64. Isikan itu pada bidang di atas. Jika masih tak cocok, jawabannya hampir selalu yang kedua — amat banyak pengirim menandatangani badan bersama sesuatu yang digabungkan padanya, bukan badan saja.
Alat terkait
- Debugger kode TOTP / 2FA
Hasilkan dan debug kode 2FA, dengan derivasi lengkap.
- Bcrypt
Buat hash bcrypt, atau periksa kata sandi terhadap hash yang ada.
- Pendekode / pemverifikasi JWT
Dekode dan verifikasi JSON Web Token — tanda tangan dan klaim.
- Pembuat hash
MD5, SHA-1, SHA-256, SHA-384, dan SHA-512 sekaligus.