مُنقِّح رموز TOTP / 2FA
أنشئ رموز TOTP / 2FA ونقّحها: الاشتقاق الكامل وفق RFC 6238، والتحقق بنافذة انجراف، وتحليل otpauth:// — كل ذلك في متصفحك.
أدخِل سرًّا لرؤية رمز.
otpauth://totp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30ما هي الأرقام الستة حقًّا
رمز TOTP — الرقم الذي يبدّله تطبيق المصادقة كل ثلاثين ثانية — ليس عشوائيًّا ولا يُخزَّن في أي مكان. يُحسب، على هاتفك وعلى الخادم معًا، من شيئين يتشاركانهما بالفعل: سرٍّ أُعِدَّ مرة واحدة عند تفعيل المصادقة الثنائية، والوقت الحالي. ولأن الطرفين يستطيعان حسابه على نحوٍ مستقل، لا يحتاج شيء إلى الانتقال بينهما عند تسجيل الدخول؛ يُجري الخادم الحساب نفسه ويتحقق من أن جوابه يطابق جوابك.
TOTP (RFC 6238) طبقةٌ رقيقة فوق مخطَّطٍ أقدم هو HOTP (RFC 4226). يحوّل HOTP سرًّا وعدّادًا إلى رمز؛ و TOTP هو ببساطة HOTP مع ضبط العدّاد على عدد خطوات الزمن منذ بداية زمن Unix. تلك هي الفكرة كلها: اقسِم زمن Unix الحالي على طول الخطوة (30 ثانية افتراضيًّا) ومرِّر الناتج إلى HOTP. تعرض هذه الأداة كل خطوة من ذلك الحساب، لأنه حين لا يُتحقق من رمز، يكون الجواب دائمًا تقريبًا مرئيًّا في مكانٍ ما من الاشتقاق.
الاشتقاق، خطوةً خطوة
خمس خطوات تنقل السرّ والوقت إلى الأرقام التي تكتبها. تطبع الأداة كلًّا منها لتقارن مع تنفيذك الخاص:
- العدّاد. خُذ زمن Unix بالثواني، واطرح T0 (0 في كل نشرٍ حقيقي)، واقسم على الدورة وقرِّب للأسفل. عند خطواتٍ من 30 ثانية، تعطي أي لحظة في نصف الدقيقة نفسه العدّاد نفسه، ولهذا يدوم الرمز ما يدوم.
- قيمة HMAC. اكتب العدّاد بثمانية بايتات بترتيب big-endian واحسب HMAC(السرّ، العدّاد) بالتجزئة المختارة — SHA-1 في معظم التطبيقات. يُنتج ذلك خلاصة بطول 20 بايت لـ SHA-1 (32 لـ SHA-256، و64 لـ SHA-512).
- الإزاحة. خُذ البتات الأربع الدنيا من آخر بايت في الخلاصة. هذا عددٌ من 0 إلى 15، ويحدّد أين تقرأ في الخلاصة — اقتطاعٌ ديناميكي، حتى لا يستخدم السرّ نفسه البايتات نفسها دائمًا.
- قيمة الـ 31 بت. اقرأ أربعة بايتات بدءًا من الإزاحة وقنِّع البت الأعلى (لتجنّب لبس الإشارة). يبقى عددٌ صحيح بطول 31 بت.
- الرمز. خُذ ذلك العدد mod 10^الأرقام واملأ باليسار بالأصفار. ستة أرقام هو الاختيار شبه العالمي؛ وسبعة وثمانية موجودان ومسموحان.
تقنيع البت الأعلى وأخذ الباقي هما الخطوتان الوحيدتان ذواتا الفقد: خلاصاتٌ كثيرة مختلفة تنطبق على الأرقام الستة نفسها، ولا بأس، لأن الرمز لا يلزم أن يصعب تخمينه إلا خلال الثلاثين ثانية التي يعيشها، لا أن يكون فريدًا إلى الأبد.
لماذا لا يتطابق رمز — الأسباب الثلاثة المعتادة
عدم تطابق TOTP لا يأتي أبدًا مع رسالة خطأ؛ الرمز ببساطة خاطئ. وعمليًّا يكون دائمًا تقريبًا واحدًا من ثلاثة، واللوحات هنا مرتَّبة للتمييز بينها:
- قُرِئ السرّ بتنسيقٍ خاطئ. سرّ المصادِق هو Base32، لكن الحروف نفسها إذا قُرئت كـ hex — أو سرٌّ كان في الحقيقة hex فقُرئ كـ Base32 — تُنتج بايتات مختلفة تمامًا ورمزًا مختلفًا تمامًا. بدّل محدِّد التنسيق وانظر أيّهما يعطي الرمز المتوقَّع.
- معامل مختلف. الافتراضي الطاغي هو HMAC-SHA-1، و6 أرقام، ودورة 30 ثانية. خادمٌ يستخدم SHA-256، أو 8 أرقام، أو خطوة 60 ثانية، سيختلف مع تطبيقٍ تُرك على الافتراضات. يحمل otpauth:// URI الثلاثة جميعًا، ولهذا يصيبها مسح رمز QR، بينما كتابة السرّ يدويًّا كثيرًا ما لا تصيبها.
- انجرفت الساعات. يفترض TOTP أن الطرفين متفقان على الوقت. إن كانت ساعة هاتفٍ متقدّمة دقيقة، فرمزه متقدّم دقيقة على رمز الخادم. لهذا وُجدت نافذة الانجراف: التحقق من رمز مقابل الخطوات على جانبَي «الآن» يخبرك لا بمجرد التطابق بل بمقدار انحراف الساعة.
يوصي RFC 6238 بنافذة تحقّقٍ لا تزيد على خطوة واحدة في كل جانب — يكفي لامتصاص انحراف الساعة المعتاد وسباق لحظة التبديل، دون توسيع فضاء التخمين أكثر من اللازم. تستخدم هذه الأداة ±1 افتراضيًّا وتتيح لك توسيعها أثناء التنقيح.
الأسرار وBase32 وotpauth:// URI
يُتشارَك السرّ مرة واحدة عند الإعداد، ويُشتق كل ما بعده منه. تُرمِّزه تطبيقات المصادقة بـ Base32 (RFC 4648) — أبجدية A–Z و2–7، تتجنّب الحروف السهلة الالتباس وتصمد عند الطباعة تحت رمز QR. تقرأ هذه الأداة Base32 افتراضيًّا، متجاهلةً المسافات التي تضيفها التطبيقات للوضوح وحالة الأحرف، وتقبل أيضًا hex لتتمكّن من إعادة إنتاج متجهات اختبار RFC 6238 التي تُعطى أسرارها كبايتات خام.
ورمز QR الذي تمسحه عند الإعداد ليس سحرًا أيضًا: إنه يرمّز otpauth:// URI بنصٍّ عادي يحمل السرّ وكل المعاملات. الصق واحدًا هنا لملء الحقول، أو ابنِ واحدًا من الحقول لنقل إعدادٍ بين التطبيقات:
otpauth://totp/GitHub:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30
يُقبَل النوع totp فقط. يحمل otpauth://hotp URI عدّادًا بدل الدورة، ومعاملته كـ TOTP سيُنتج بصمت رموزًا خاطئة — لذا يُرفَض بدل أن يُخمَّن.
الخوارزمية والأرقام والدورة
يسمح RFC 6238 بـ HMAC-SHA-1 أو SHA-256 أو SHA-512، ومن ستة إلى ثمانية أرقام، وأي طول خطوة. عمليًّا استقرّ العالم على SHA-1 وستة أرقام وثلاثين ثانية، ومعظم التطبيقات لا تنفّذ إلا ذلك التركيب — فخادمٌ يختار غير ذلك عليه أن يأمل أن يتبعه تطبيق المستخدم، وكثيرٌ لا يتبع. الاختيار الآمن للتشغيل البيني هو الممل.
يستحق أمر SHA-1 معالجةً مباشرة، لأن أداة التجزئة في هذا الموقع تصف SHA-1 بأنه مكسور. كلا القولين صحيح. SHA-1 غير صالح للتواقيع الرقمية لأن المهاجمين يستطيعون تصنيع تصادمات — وثيقتين بالتجزئة نفسها. لا يعتمد TOTP على تلك الخاصية: أمانه يأتي من المفتاح السرّي داخل HMAC، لا من مقاومة التجزئة للتصادم، ويظل HMAC-SHA-1 سليمًا. استخدام SHA-256 هنا يمكن الدفاع عنه لكنه يفيد قليلًا، ويكلّف التشغيل البيني مع تطبيقاتٍ لا تجيد سوى SHA-1.
ما تحميه هذه الأداة وما لا تحميه
كل شيء هنا يعمل في متصفحك. تُحسب قيمة HMAC عبر Web Crypto API على جهازك — البدائية نفسها التي تستخدمها أداتا التجزئة و HMAC — ولا شيء مما تكتبه — سرّ أو رمز أو otpauth URI — يُرفَع أو يُخزَّن أو يُسجَّل. هذه خاصيةٌ لكون الشيفرة على جانب العميل، لا وعدٌ عليك تصديقه.
ومع ذلك فسرّ TOTP عاملٌ ثانٍ: من يملكه يستطيع توليد رموزك. لصق سرّ إنتاجي في أي صفحة ويب — بما فيها هذه — يضعه في الحافظة وربما في سجل المتصفح، فعامله بالعناية نفسها التي تعامل بها كلمة مرور، وفضِّل سرًّا مؤقتًا أو للاختبار حين تريد فقط فهم الآلية. الأداة موجودة للتنقيح والتعلّم، لا لتكون المكان الذي يعيش فيه عاملك الثاني الحقيقي.
الأسئلة الشائعة
- هل يُرسَل سرّي إلى خادم؟
- لا. يُحسب الرمز في متصفحك عبر Web Crypto API، ولا شيء مما تكتبه يُرفَع أو يُسجَّل. ولأن سرّ TOTP عاملٌ ثانٍ، كُن حذرًا مع ذلك عند لصق سرٍّ إنتاجي — فقد يمرّ عبر الحافظة وسجل المتصفح كأي نص.
- لماذا لا يتطابق رمزي مع تطبيق المصادقة لديّ؟
- غالبًا واحد من ثلاثة: قُرئ السرّ بتنسيق خاطئ (Base32 مقابل hex)، أو اختلف معامل عن الافتراضات (معظم التطبيقات SHA-1، و6 أرقام، ودورة 30 ثانية)، أو انجرفت ساعة الجهاز. تعزل لوحة الاشتقاق الأولين، ويكشف التحقق بنافذة انجراف ± الثالث.
- ما الفرق بين TOTP و HOTP؟
- يحسب HOTP (RFC 4226) رمزًا من سرٍّ وعدّادٍ يتزايد مع كل استخدام. و TOTP (RFC 6238) هو البنية نفسها مع ضبط العدّاد على عدد خطوات الزمن منذ بداية زمن Unix، فيتغيّر الرمز مع الساعة لا مع ضغطة زرّ. TOTP هو ما تستخدمه تطبيقات المصادقة.
- لماذا SHA-1 هو الافتراضي وهو مكسور في مواضع أخرى؟
- SHA-1 مكسور للتواقيع لأنه يمكن بناء تصادمات، لكن HMAC — الذي يقوم عليه TOTP — لا يعتمد على مقاومة التصادم؛ أمانه يقوم على المفتاح السرّي. HMAC-SHA-1 سليم، وهو الخوارزمية الوحيدة التي تنفّذها كثيرٌ من تطبيقات المصادقة، فهو الافتراضي الآمن والمتوافق معًا.
- هل يمكنني تثبيت الرمز على وقتٍ محدَّد؟
- نعم. بدّل الوقت من مباشر إلى مثبَّت وأدخِل طابع زمن Unix. عندئذٍ يبقى الرمز ساكنًا، وهكذا تُعيد إنتاج متجه اختبارٍ منشور — يعطي RFC 6238 قيمًا عند أوقاتٍ مثل 59 و1111111109 — أو تفحص أي رمزٍ كان صالحًا في لحظةٍ ماضية.
- ما حجم نافذة الانجراف الذي ينبغي؟
- يوصي RFC 6238 بخطوة واحدة على الأكثر في كل جانب، وهو ما تستخدمه هذه الأداة افتراضيًّا. النافذة الأوسع تحتمل ساعةً أكثر انجرافًا لكنها توسِّع أيضًا مجموعة الرموز التي يقبلها الخادم، فهي مقايضة؛ و±1 هو التوازن القياسي.
- ما فائدة الأرقام والدورة؟
- الأرقام هي عدد خانات الرمز — ستة في كل مكان تقريبًا، وسبعة أو ثمانية حيث تريد خدمة قوة أكبر قليلًا. الدورة هي عدد الثواني التي يظل فيها الرمز صالحًا، وثلاثون افتراضيًّا. كلاهما يدخل في otpauth:// URI، وكلاهما يجب أن يتطابق على الجانبين وإلا لن تتوافق الرموز.