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

الملف لم يكن قط التعرض الذي تصورته

الملف المؤقت خطر ملموس حين يكون مقروءًا للجميع، أو حين يبقى بعد انهيار، أو حين تُتخطّى خطوة تنظيف بعد استثناء. هذه مخاطر حقيقية وتستحق الإصلاح. وهي أيضًا محلية وظاهرة ويسهل اختبارها. سمِّ كل واحدة منها في نصك قبل أن تستنتج أن التغيير شكلي.

المخاطر الأهدأ تقع في المصبّ: المفتاح المطبوع أثناء التنقيح، والاستثناء الذي يسلِّل كائن النتيجة كله، ومعالج الانهيار الذي يكتب تفريغ الذاكرة، ومجمّع السجلات الذي يتلقى مسار الملف ثم محتواه. تجنّب الملف المؤقت لا يفعل شيئًا لأي منها، والاعتقاد بغير ذلك هو كيف تترك إعادة كتابة حسنة النية السر أكثر انكشافًا من قبل. تعامل مع التغيير كتحسين واحد في سلسلة، لا كالإصلاح.

ما يكتبه العميل عندما لا يُعطى اسم ملف

ترسل إصدارات العميل الحالية المفتاح المولَّد إلى المخرجات القياسية عندما يُعطى أمر المفتاح دون مسار إخراج. هذا السلوك الموثَّق هو ما يجعل نهج الذاكرة ممكنًا، وهو يزيل الحاجة إلى الحيلة الأقدم بتوجيه الأداة إلى مسار جهاز.

import subprocess
proc = subprocess.run(
    ["openvpn", "--genkey", "tls-crypt"],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    check=True,
)
key_material = proc.stdout

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

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

تدفقان، معنيان

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

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

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

إذا أردت حفظه، فافعل ذلك عن قصد

تحتاج معظم عمليات النشر في النهاية إلى المفتاح على القرص، على البوابة أو في مخزن أسرار. اكتبه مرة واحدة، بأذونات مقيّدة من لحظة الإنشاء لا عبر chmod لاحق، واجعل الكتابة ذرّية كي لا يصبح ملف جزئي هو الذي يقرأه خدمة عند الإقلاع. إعادة التسمية من مسار في الدليل نفسه تكفي عادة لذلك. احذف مسار التجهيز في فرع الفشل، لأن الكتابة الفاشلة هي بالضبط النسخة التي ينساها الناس.

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

المفتاح المشترك ليس هوية

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

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

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

مقالات ذات صلة