HMAC підпис
Порахувати HMAC із секретним ключем
Дані не залишають ваш браузер
Цей інструмент повністю працює на вашому пристрої: обчислення виконує JavaScript у вкладці. Ми не надсилаємо введений текст на сервер, не зберігаємо і не логуємо його. Можете сміливо працювати з робочими даними - і навіть відключити інтернет після завантаження сторінки.
Що таке HMAC
HMAC - це хеш, порахований разом із секретним ключем. Звичайний SHA-256 може порахувати будь-хто; HMAC - лише той, хто знає секрет. Тому він доводить не тільки цілісність даних, а й авторство.
Формально це «код автентифікації повідомлення»: підпис, який підтверджує, що дані надіслав власник ключа і по дорозі їх не змінили.
Головне застосування - вебхуки
Коли Stripe, GitHub чи LiqPay надсилають вам вебхук, вони підписують тіло запиту вашим секретом. Ви рахуєте HMAC самі і порівнюєте. Збіглося - запит справжній; ні - хтось намагається підробити подію.
Без перевірки підпису вебхук-ендпоінт означає, що будь-хто в інтернеті може повідомити вашому застосунку про «успішну оплату».
Як перевіряти правильно
$signature = hash_hmac('sha256', $request->getContent(), config('services.stripe.webhook_secret'));
// ТІЛЬКИ hash_equals: === порівнює побайтово і зупиняється на першій
// розбіжності, а різниця в часі дозволяє підібрати підпис символ за символом.
if (! hash_equals($signature, $request->header('X-Signature'))) {
abort(403);
}
Три речі, які роблять неправильно:
- Порівняння через
===- вразливо до timing-атак. - Хешування розпарсеного тіла замість сирого.
$request->all()уже змінив дані; підпис рахується від байтів, які прийшли:$request->getContent(). - Ігнорування часової мітки. Без неї перехоплений валідний запит можна відтворити будь-коли. Тому підписують
timestamp.bodyі відкидають старі запити.
У Laravel
// Вебхук треба вивести з-під CSRF - у нього немає сесії
// bootstrap/app.php
$middleware->validateCsrfTokens(except: ['webhooks/*']);
// Підписані URL - готовий механізм, коли підпис потрібен для своїх посилань
URL::temporarySignedRoute('unsubscribe', now()->addDays(7), ['user' => $user->id]);
// Перевіряється middleware 'signed'
Route::get('/unsubscribe/{user}', ...)->middleware('signed');
Про безпеку цієї сторінки
Ключ, який ви вводите вище, не залишає ваш браузер: HMAC рахує Web Crypto API у вкладці. Та все ж для справжнього продакшн-секрету краще скористатися локальним php artisan tinker - звичка не вставляти робочі ключі в жоден сайт корисніша за будь-які гарантії.