الخلاصة

  • يقدّم RFC 9846 القاعدة الحالية لـ TLS 1.3: تحدّث KeyUpdate سر مرور التطبيقات في اتجاه إرسال واحد. تُشفّر رسالة الانتقال بالمفتاح القديم، ثم تستخدم سجلات المرسل اللاحقة الجيل الجديد ويحدّث المستقبل سلسلة الاستقبال المقابلة.
  • ينشئ update_requested واجباً مقابلاً محدوداً، لا ملكية عن بعد للاتصال. يظل الاتجاهان مستقلين، وقد تدفع الطلبات المتقاطعة كليهما جيلين، ويمكن دمج الطلبات أثناء الصمت، وتبقى حدود الجيل والاستخدام تحت القرار المحلي.
  • يجب أن يميّز الدليل بين جدولة التحديث وإرساله وقبوله ونجاح أول بيانات تطبيق بالجيل الجديد. لا تثبت هذه المراحل محو السر القديم ولا تجديد المصادقة ولا تفويض عمل التطبيق.

اتصال واحد وسلسلتان غير متزامنتين

لنفترض أن قناة TLS طويلة العمر تحمل بيانات تشغيلية مستمرة. قرر العميل تحديث مفتاح الإرسال وطلب من الخادم أن يفعل الشيء نفسه. تبدو العملية كأنها تدوير واحد، غير أن السلك لا يحتوي ساعة مشتركة تقلب الحالتين معاً.

يشفر العميل رسالة KeyUpdate بمفتاحه الحالي. بعد إرسالها، ينتقل كل سجل لاحق منه إلى سر مرور التطبيق التالي. لا يحدّث الخادم سلسلة الاستقبال إلا بعد توثيق الرسالة القديمة. وإذا استجاب، يرسل رسالته تحت مفتاح الإرسال القديم الخاص به، ثم ينقل المرور اللاحق في الاتجاه الآخر إلى الجيل التالي.

لكل اتجاه سر وتسلسل سجلات وموعد تنفيذ. ولهذا فإن عداداً واحداً باسم «نسخة مفتاح الاتصال» يخفي الفرق بين طلب عالق، وتحديث مجدول لم يصل إلى الشبكة، وطلبين التقيا في الطريق.

النص الحالي هو RFC 9846

حل RFC 9846 محل RFC 8446 في عام 2026 مع الحفاظ على توافق TLS 1.3 على السلك. بقيت KeyUpdate رسالة المصافحة من النوع 24، وبقيت لها قيمتان صالحتان فقط: update_not_requested(0) وupdate_requested(1).

إذا وصلت قبل Finished وجب إنهاء الاتصال بتنبيه unexpected_message. أما القيمة غير المعروفة فتؤدي إلى illegal_parameter. ويجب أن تنتهي الرسالة عند حد السجل السابق لتغيير المفتاح. لا يجوز للمستقبل قبول بيانات الجيل التالي قبل توثيق جسر الانتقال بالمفتاح القديم، وإلا أمكن تحويل التخمين إلى ثغرة قطع للاتصال.

يشتق سر المرور التالي من السر الاتجاهي الحالي بواسطة HKDF-Expand-Label والوسم traffic upd، ثم تشتق منه قيمة المفتاح وIV. ويحدد النص الحالي أقصى حقبة إرسال عند 2^48-1. لا يفرض المستقبل هذا الحد بالنيابة عن المرسل لأن مواصفة لاحقة قد تغير قاعدة الإرسال.

الطلب الموثق ليس أمراً مفتوحاً

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

لا يجوز ترك أكثر من طلب تحديث مقابل واحد معلقاً. ويمكن لتحديث واحد أن يجيب عن طلبات متعددة وصلت أثناء صمت النظير. وإذا أرسل الطرفان طلبين في الوقت نفسه فتقاطعا، يرد كل طرف أيضاً؛ وقد يتقدم الاتجاهان جيلين بدلاً من جيل واحد.

إذا كانت الاستجابة ستتجاوز سقف الحقبة المحلية، فلا ينفذها المرسل وينبغي أن يتجاهل علم الطلب. وقد يضطر لاحقاً إلى إنهاء الاتصال عند بلوغ حد AEAD. إذن، لا يمنح الطلب الصحيح حقاً بلا نهاية في استهلاك المعالج أو توليد الأسرار أو إبقاء الاتصال حياً.

الاشتقاق يثبت الاستمرار لا المحو

لا يستطيع مراقب لا يملك السر الحالي القفز إلى الجيل التالي بمجرد رؤية الحركة. هذه خاصية استمرارية مهمة. لكن حذف السر السابق يحدث داخل ذاكرة التنفيذ. يوصي RFC بمحو السر القديم والمفاتيح التابعة له بعد الاشتقاق، ولا تستطيع رسالة مقابلة فحص heap بعيد أو وحدة عتادية أو جدول offload أو ملف تعطل أو نسخة احتياطية.

إثبات المحو ادعاء محلي يحتاج أدلة من دورة حياة الذاكرة. أما نجاح سجل جديد فيثبت فقط أن الطرفين اشتقا سلسلة متوافقة. الخلط بينهما يجعل حدث تشغيل متبادل شهادة ضمان زائفة.

ولا تعيد KeyUpdate توثيق الهوية. فهي لا تطلب شهادة خادم جديدة، ولا تعيد التحقق من اسم الخدمة، ولا تبدل هوية العميل، ولا توافق على أمر في طبقة التطبيق. تستطيع مفاتيح جديدة تماماً حماية قرار تجاري غير مصرح به.

واجهة الاستدعاء ليست لحظة السلك

تسمح OpenSSL باستدعاء SSL_key_update() بعد المصافحة الأولية، لكن النجاح يعني جدولة العمل. لا يحدث الإرسال إلا عندما تدفع عملية I/O لاحقة أو استدعاء صريح للمصافحة الحالة إلى الأمام. وعلى التطبيق تنسيق الكتابات المعلقة؛ فلا يصلح زمن رجوع الدالة كوقت للانتقال.

تظهر GnuTLS الاتجاه صراحة: يحدّث الاستدعاء الإرسال المحلي وحده ما لم يُستخدم GNUTLS_KU_PEER لطلب الاتجاه المقابل. وقد يعيد حالات عدم الحجب مثل إرسال السجلات. كما تفرق وثائقه بين إعادة التشفير وإعادة المصادقة.

يتيح rustls وظيفة refresh_traffic_keys() ويتابع حدود السرية في المسار المعتاد. وإذا نقل التطبيق حماية السجلات إلى واجهة kernel، أصبح مسؤولاً عن تقدير العدد والتحديث والإيقاف. تغيير مكان التشفير لا يغيّر صاحب المساءلة.

لكل من TLS وDTLS وQUIC أثر مختلف

يستخدم QUIC مصافحة TLS 1.3 لكنه يمنع رسائل TLS KeyUpdate. يغير QUIC الإصدار الأول مفاتيح الحزم عبر Key Phase وتسلسل الإقرار واشتقاق quic ku. لذا فإن مراقبة عداد KeyUpdate على اتصال QUIC ستسجل صفراً حتى لو تم التحديث كما ينبغي.

يحتفظ DTLS 1.3 بـ KeyUpdate في وسط يقبل الضياع وإعادة الترتيب. يستعمل الحقب والإقرارات، ويحتفظ أحياناً بمفاتيح استقبال أقدم للرزم المتأخرة. وقد تتقاطع الاستجابة مع الطلب، ولذلك لا تعد إقراراً ضمنياً به.

جمع هذه الحالات تحت تسمية «تبديل مفتاح TLS» يفقد الدليل معناه. في TLS المتدفق نحتاج جسر السجل المرتب؛ وفي DTLS نحتاج حركة الحقبة والإقرار؛ وفي QUIC نحتاج مرحلة مفتاح الحزمة.

سجل يشرح السلطة من دون نسخ الأسرار

يكفي أن يسجل النظام مرجع الاتصال والدور والنقل والإصدار والاتجاه والجيلين القديم والجديد. ويضيف سبب البدء — سياسة محلية أو حد مكتبة أو مشغل أو طلب نظير — وقيمة الطلب وحالته المعلقة وتوثيق جسر المفتاح القديم وحد السجل وأول بيانات ناجحة بالجيل الجديد وأي دمج أو تقاطع أو تنبيه نهائي.

ينبغي فصل أربع لحظات: مجدول، مُرسل، مقبول، ومستخدم بنجاح. ويبقى دليل محو الذاكرة في سجل ضمان محلي منفصل. لا تكفي حزمة ملتقطة لأن TLS 1.3 يشفر KeyUpdate؛ ويمكن في الاختبار المنضبط ربط callbacks والعدادات بالانتقال من دون نسخ مادة المفتاح إلى المراقبة الإنتاجية.

المصادر