مولّد HMAC

احسب HMAC لنص أو بايتات ست عشرية أو ملف باستخدام مفتاح سري وخوارزمية SHA-256 أو SHA-384 أو SHA-512 أو SHA-1 أو MD5، وقارنه بتوقيع webhook أو واجهة API. ولا يغادر أي شيء متصفحك.

تعمل بالكامل داخل متصفحك، ولا يُرفع أي شيء.

طريقة الاستخدام

  1. اختر «الخوارزمية». تكون HMAC-SHA256 محددة افتراضيًا، وهي التي تستخدمها معظم خدمات webhook وواجهات API.
  2. أدخل «المفتاح السري» واضبط «صيغة المفتاح» على «نص» (يُقرأ بترميز UTF-8) أو «ست عشري» أو «Base64». واستخدم «ست عشري» أو «Base64» عندما يكون المفتاح بايتات خام لا سلسلة تشبه كلمة المرور.
  3. اكتب «الرسالة» أو الصقها، أو غيّر «صيغة المدخلات» إلى «ست عشري» لإدخال بايتات خام، أو افتح ملفًا عبر «فتح ملف». وتتحدّث قيمة HMAC أثناء الكتابة.
  4. اختر في «صيغة المخرجات» «ست عشري (أحرف صغيرة)» أو «ست عشري (أحرف كبيرة)» أو «Base64» وانسخ النتيجة، أو الصق توقيعًا تلقيته في «المقارنة مع» لترى «متطابقة» أو «غير متطابقة».

كيف يعمل HMAC

يجمع HMAC (رمز مصادقة الرسائل المعتمد على التجزئة، RFC 2104) بين دالة تجزئة تشفيرية ومفتاح سري. ولا يستطيع إنتاج القيمة الصحيحة لرسالة ما إلا من يعرف المفتاح، لذا تثبت قيمة HMAC المتطابقة أمرين معًا: أن الرسالة لم تُعدَّل، وأنها صدرت عن جهة تملك المفتاح.

البنية هي H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ message)). فإذا كان المفتاح أطول من حجم كتلة دالة التجزئة (64 بايتًا لـ MD5 وSHA-1 وSHA-256، و128 لـ SHA-384 وSHA-512) تُحسب تجزئته أولًا، ثم يُحشى بالأصفار حتى يبلغ هذا الحجم، ثم تُطبَّق عليه عملية XOR مع ipad (بايتات 0x36) لحساب تجزئة داخلية على الرسالة، ومع opad (بايتات 0x5c) لحساب تجزئة خارجية على النتيجة الداخلية. أما الصيغة الساذجة SHA-256(key ‖ message) فليس لها تجزئة خارجية، لذا يستطيع أي شخص يرى وسم مصادقة واحدًا أن يُلحق بيانات بالرسالة ويحسب وسمًا جديدًا صالحًا دون المفتاح (هجوم تمديد الطول).

يساوي طول المخرجات طول مخرجات دالة التجزئة المستخدمة: 32 بايتًا، أي 64 حرفًا ست عشريًا، في HMAC-SHA256. ويوصي RFC 2104 بمفتاح لا يقل عن هذا الطول، ويولّد مولّد Base64 العشوائي مفاتيح مناسبة.

أين تُستخدم تواقيع HMAC

  • Webhooks في GitHub. قيمة الترويسة X-Hub-Signature-256 هي sha256= متبوعة بقيمة HMAC-SHA256 الست عشرية لجسم الطلب الخام، محسوبة بالمفتاح السري للـ webhook. ويمكنك لصق قيمة الترويسة كاملة في «المقارنة مع»، إذ تُتجاهل البادئة sha256=.
  • Webhooks في Stripe. تحمل الترويسة Stripe-Signature طابعًا زمنيًا t وتوقيعًا v1، وهو قيمة HMAC-SHA256 الست عشرية للطابع الزمني ثم نقطة ثم الجسم الخام، محسوبة بالمفتاح السري لنقطة النهاية (whsec_...) مستخدَمًا بوصفه نصًا.
  • Webhooks في Shopify. تحمل الترويسة X-Shopify-Hmac-Sha256 قيمة HMAC-SHA256 للجسم الخام بترميز Base64، محسوبة بالمفتاح السري للعميل (client secret) الخاص بالتطبيق، لذا اختر مخرجات «Base64» أو الصق قيمة الترويسة في «المقارنة مع».
  • AWS Signature Version 4. يُشتق مفتاح التوقيع بسلسلة من عمليات HMAC-SHA256: التاريخ بمفتاح هو AWS4 مضافًا إليه مفتاح الوصول السري، ثم المنطقة، ثم الخدمة، ثم aws4_request، وكلٌّ منها بمفتاح هو النتيجة السابقة. اضبط «صيغة المفتاح» على «ست عشري» لتمرير مخرجات كل خطوة إلى الخطوة التالية.
  • JSON Web Tokens. الخوارزميات HS256 وHS384 وHS512 هي HMAC-SHA256 و-384 و-512 محسوبة على الترويسة المرمّزة ثم نقطة ثم الحمولة المرمّزة. والجزء الثالث من الرمز هو قيمة HMAC هذه بترميز Base64 الآمن لعناوين URL، ويقبلها حقل «المقارنة مع» كما هي. وتتحقق أداة فك ترميز JWT من الرموز كاملة.

احسب HMAC دائمًا على الجسم الخام تمامًا كما وصل. فتحليل JSON ثم إعادة تسلسله يغيّر المسافات أو ترتيب المفاتيح، وحتى سطر جديد زائد واحد يعطي قيمة HMAC مختلفة تمامًا.

HMAC في الشيفرة البرمجية

# Python
import hmac, hashlib
sig = hmac.new(b'key', b'message', hashlib.sha256).hexdigest()
hmac.compare_digest(sig, received)        # مقارنة بزمن ثابت

// Node.js
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', 'key').update('message').digest('hex');
// تُطلق timingSafeEqual خطأً إذا اختلف الطولان، لذا تحقّق منهما أولًا
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(received));

// PHP: تأتي الرسالة قبل المفتاح
$sig = hash_hmac('sha256', 'message', 'key');
hash_equals($sig, $received);

# OpenSSL: مفتاح نصي، ثم المفتاح نفسه بالصيغة الست عشرية
printf '%s' 'message' | openssl dgst -sha256 -hmac 'key'
printf '%s' 'message' | openssl dgst -sha256 -mac HMAC -macopt hexkey:6b6579

# متجه اختبار: المفتاح "key"، والرسالة "The quick brown fox jumps over the lazy dog"
# HMAC-SHA256 = f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

عندما تتحقق من توقيع في شيفرتك، استخدم مقارنة بزمن ثابت مثل تلك الواردة أعلاه. فالمقارنة العادية == تتوقف عند أول حرف مختلف، وقد يتيح فرق التوقيت هذا للمهاجم أن يعثر على توقيع صالح بايتًا تلو الآخر. وفي المخططات التي تتضمن طابعًا زمنيًا، مثل مخطط Stripe، ارفض أيضًا الطلبات التي يزيد عمر طابعها الزمني على بضع دقائق، فهذا يمنع هجمات إعادة الإرسال.

الأسئلة الشائعة

هل ما زال HMAC-MD5 أو HMAC-SHA1 آمنًا؟

تكسر هجمات التصادم MD5 وSHA-1 بوصفهما دالتي تجزئة عاديتين، لكنها لا تتيح طريقة عملية لتزوير HMAC، الذي يعتمد على خصائص أخرى لدالة التجزئة وعلى مفتاح سري (يناقش RFC 6151 حالة HMAC-MD5). ولا بأس بالإبقاء على عمليات التكامل التي تتطلبهما، مثل رموز TOTP المبنية على HMAC-SHA1. أما في التصاميم الجديدة، فاستخدم HMAC-SHA256.

لماذا لا تطابق قيمة HMAC لديّ توقيع webhook؟

الأسباب المعتادة: حساب التجزئة على JSON بعد تحليله وإعادة تسلسله بدلًا من الجسم الخام، أو سطر جديد زائد في نهاية الرسالة، أو مفتاح سري خاطئ أو صيغة مفتاح خاطئة (مفتاح Base64 أو ست عشري أُدخل بصيغة «نص»، أو العكس)، أو خوارزمية خاطئة. أما الاختلاف بين الست عشري وBase64 فلا يمثل مشكلة هنا، إذ يقبل حقل «المقارنة مع» الصيغة الست عشرية بأحرف كبيرة أو صغيرة، وBase64 القياسي، وBase64 الآمن لعناوين URL.

ما الفرق بين HMAC والتجزئة العادية؟
يستطيع أي شخص حساب تجزئة عادية مثل SHA-256، لذا فهي تُظهر فقط أن البيانات لم تتغير عن طريق الخطأ. أما HMAC فلا يمكن حسابه إلا بالمفتاح السري، لذا تُظهر القيمة الصالحة منه أيضًا أنها صدرت عن شخص يملك ذلك المفتاح.
هل HMAC هو نفسه التوقيع الرقمي؟

لا. يتشارك طرفا HMAC سرًا واحدًا، لذا فكل من يستطيع التحقق من وسم يستطيع أيضًا إنشاءه. أما التواقيع مثل RSA أو ECDSA (أي RS256 أو ES256 في JWT) فتُنشأ بمفتاح خاص ويُتحقق منها بمفتاح عام، فلا يستطيع من يتحقق منها تزويرها.

هل يُرسل مفتاحي السري إلى خادم؟

لا. تُحسب HMAC-SHA1 وأنواع SHA-2 باستخدام واجهة Web Crypto API في متصفحك، وتُحسب HMAC-MD5 بواسطة JavaScript في الصفحة. ولا يغادر المفتاح ولا الرسالة جهازك أبدًا. ومع ذلك، تعامل بحذر مع الأسرار المستخدمة في بيئة الإنتاج، وبدّل المفتاح إذا كان من المحتمل أنه انكشف.