Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

التشفير والأمان

توفّر وحدة تأكيدات (تحتاج استيراد) دوال هاش وتشفير متماثل، إضافة إلى دوال التأكيد المعروفة (تأكد_يساوي وأخواتها).

استورد تأكيدات

هاش — SHA-256

اطبع_سطر(هاش("مرحبا"))

هاش(نص) يُرجع بصمة SHA-256 (FIPS 180-4) كنصّ ست عشريّ من 64 حرفًا، بصرف النظر عن طول المدخل. التنفيذ مطابق حرفيًّا بين المفسّر والمترجم — نفس المدخل يُنتج نفس الهاش على كلا المحرّكين دائمًا.

هاش("")     # e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
هاش("abc")  # ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

شفّر / فك_تشفير — SHA-256-CTR

متغير مشفّر = شفّر("سر", "مفتاح")
اطبع_سطر(فك_تشفير(مشفّر, "مفتاح"))   # سر

شفّر(نص، مفتاح) تشفير متماثل مبنيّ على SHA-256 بنمط العدّاد (CTR): مقطع عشوائي (nonce) من 8 بايت يُضاف لبداية الناتج، وكل كتلة 32 بايت من النصّ تُخفى بـSHA-256(مفتاح ‖ nonce ‖ عدّاد) كتيّار مفاتيح XOR. الناتج نصّ ست عشريّ، ويختلف مع كل استدعاء حتى لنفس المدخلات (بسبب الـnonce العشوائي) — لذا لا يصلح اختبار الناتج الخام حرفيًّا، بل التبادليّة:

فك_تشفير(شفّر(نص، مفتاح), مفتاح) == نص   # صحيح دائمًا

النصّ المشفّر بأحد المحرّكين (مفسّر/مترجم) يُفكّ بالآخر دون مشكلة — نفس الخوارزميّة بالضبط في الاثنين.

تنبيه أمنيّ: هذا تشفير متماثل بسيط (CTR بلا مصادقة/tag) وليس بديلًا عن معايير موثوقة كـAES-GCM عند الحاجة لمقاومة العبث (tampering). مناسب لإخفاء بيانات داخل تدفّق تتحكّم فيه، لا لتخزين أسرار حسّاسة عالية المخاطر.

ملاحظة تنفيذيّة

لا توجد وحدة stdlib/crypto منفصلة قائمة على OpenSSL — هذه الدوال مُنفَّذة ذاتيًّا (self-rolled) داخل وقت التشغيل المشترك بين المفسّر والمترجم، لتبقى الوحدة قابلة للعمل حتى في أهداف الوضع الحرّ (freestanding) التي لا يمكنها الربط بمكتبات نظام تشغيل مضيف.

وحدة تشفير — المكتبة الموسَّعة

وحدة تشفير (منفصلة عن تأكيدات أعلاه) توفّر مكتبة تشفير حديثة أوسع: هاش/مصادقة (BLAKE3)، اشتقاق مفاتيح (PBKDF2/HKDF/Argon2id)، تشفير موثَّق (AEAD)، وتبادل مفاتيح + تواقيع رقميّة على منحنى Curve25519 (X25519/Ed25519). كل الدوال ذاتيّة التنفيذ بالكامل (بلا OpenSSL) فتعمل على هدف الوضع الحرّ كذلك، ومطابقة حرفيًّا بين المفسّر والمترجم — نفس المدخل يُنتج نفس المخرَج عبر كلا المحرِّكين دائمًا، ومُتحقَّقة مقابل شعاعات الاختبار الرسميّة لكل معيار (RFC/مسابقة قياسيّة).

استورد تشفير

بلايك3 / هاش_مفتاح — BLAKE3

اطبع_سطر(بلايك3("مرحبا"))
اطبع_سطر(هاش_مفتاح("رسالة", "سرّ"))

بلايك3(نص) يُرجع هاش BLAKE3 (256 بت) كسلسلة ست عشريّة من 64 حرفًا — أحدث وأسرع من هاش (SHA-256)، ومُتحقَّق مقابل شعاعات BLAKE3 الرسميّة.

هاش_مفتاح(رسالة، مفتاح) مصادقة رسالة (MAC) عبر نمط BLAKE3 المُفتاح الأصيل — أبسط من HMAC التقليديّ لأنّ الحماية من هجمات امتداد الطول جزء من تصميم الخوارزميّة نفسها، لا طبقة إضافيّة. إن كان طول المفتاح 32 بايت يُستعمَل مباشرة، وإلّا يُشتقّ منه مفتاح 32 بايت عبر بلايك3(مفتاح) أوّلًا.

اشتق_مفتاح_مرور / اشتق_مفتاح / أرجون2 — اشتقاق المفاتيح (KDF)

ثلاث دوال اشتقاق مفتاح لأغراض مختلفة — لا تبادل بينها:

اطبع_سطر(اشتق_مفتاح_مرور("كلمة_سرّ", "ملح", 100000))
اطبع_سطر(اشتق_مفتاح("سرّ_مشترك", "ملح", "سياق", 16))
اطبع_سطر(أرجون2("كلمة_سرّ", "ملح_عشوائي_٨_بايت_فأكثر", 65536, 3))
الدالّةالمعيارالغرض
اشتق_مفتاح_مرور(كلمة_المرور، ملح، عدد_التكرارات)PBKDF2-HMAC-SHA256 (RFC 2898/8018)إبطاء زمنيّ فقط؛ عدد_التكرارات معامل تحكّم صريح (يُنصح بـ100000 فأكثر)
اشتق_مفتاح(سرّ، ملح، سياق، الطول)HKDF-SHA256 (RFC 5869)توسيع/تقسيم سرّ (مثل ناتج تبادل_مفتاح) إلى مفاتيح فرعيّة مستقلّة بالسياق؛ الطول بين 1 و8160 بايت
أرجون2(كلمة_المرور، ملح، تكلفة_الذاكرة، عدد_التكرارات)Argon2id (RFC 9106)إبطاء زمنيّ وذاكريّ معًا — مقاومة أقوى لتسريع الاختراق بعتاد مخصَّص (ASIC/GPU) من PBKDF2؛ تكلفة_الذاكرة بالكيلوبايت (8 فأكثر، يُنصح بعشرات الآلاف لكلمات المرور)، الملح 8 بايت على الأقلّ

استعمل اشتق_مفتاح_مرور أو أرجون2 لاشتقاق مفتاح من كلمة مرور (بطء مقصود لمقاومة التخمين)، واشتق_مفتاح لتوسيع سرّ عشوائيّ موجود أصلًا (كناتج تبادل مفاتيح) إلى عدّة مفاتيح مستقلّة — لا لكلمات مرور.

تنبيه: جميع هذه الدوال تفشل بخطأ صريح على بارامترات خارج الحدود الآمنة الموصى بها في المعيار المرجعيّ (مثلًا عدد_التكرارات صفر، أو تكلفة_الذاكرة أقلّ من 8، أو ملح أقصر من 8 بايت لـأرجون2)، لا تنفّذ بصمت بقيم ضعيفة.

شفر_موثق / فك_تشفير_موثق — تشفير موثَّق (AEAD)

متغير مغلف = شفر_موثق("سرّ حسّاس", "مفتاح_كلمة_مرور")
اطبع_سطر(فك_تشفير_موثق(مغلف, "مفتاح_كلمة_مرور"))

شفر_موثق/فك_تشفير_موثق تشفير موثَّق (AEAD) عبر ChaCha20-Poly1305 (RFC 8439) — بخلاف شفّر/فك_تشفير أعلاه (تشفير بلا مصادقة)، ينتج شفر_موثق وسم مصادقة Poly1305 يكشف أيّ عبث بالنصّ المشفَّر عند فكّه. المفتاح: يُستعمَل مباشرةً إن كان 32 بايت، وإلّا يُشتقّ منه مفتاح عبر SHA-256. يُولَّد nonce عشوائيّ جديد لكلّ استدعاء، فتشفير النصّ نفسه مرّتين ينتج مغلَّفين مختلفين — سلوك مقصود لا خلل.

⚠️ فشل المصادقة يتباعد بين المحرِّكين عمدًا: عند مفتاح خاطئ أو مغلَّف مُعبَث به، المفسّر يرمي خطأً قابلًا للالتقاط بـحاول/امسك؛ المترجم يفشل مُغلَقًا (fail-closed) — رسالة عامّة على stderr ثمّ إنهاء البرنامج، لأنّ وقت تشغيل المترجم لا يملك اليوم مسار استثناء قابلًا للالتقاط من كود C. الاثنان لا يُرجعان أبدًا نصًّا مُحرَّفًا صامتًا — فقط آليّة الإبلاغ عن الفشل تختلف.

ولّد_مفتاح_خاص_x25519 / اشتق_مفتاح_عام_x25519 / تبادل_مفتاح — تبادل مفاتيح X25519

متغير أ_خاص = ولّد_مفتاح_خاص_x25519()
متغير ب_خاص = ولّد_مفتاح_خاص_x25519()
متغير ب_عام = اشتق_مفتاح_عام_x25519(ب_خاص)
متغير سرّ_مشترك = تبادل_مفتاح(أ_خاص, ب_عام)
اطبع_سطر(اشتق_مفتاح(سرّ_مشترك, "ملح", "جلسة", 32))

تبادل مفاتيح ديفي-هيلمان على منحنى Curve25519 (X25519، RFC 7748):

  • ولّد_مفتاح_خاص_x25519() — يولّد مفتاحًا خاصًّا عشوائيًّا جديدًا (32 بايت).
  • اشتق_مفتاح_عام_x25519(مفتاح_خاص) — يشتقّ المفتاح العامّ المقابل حتميًّا.
  • تبادل_مفتاح(مفتاح_خاص، مفتاح_عام_الطرف_الآخر) — يُنتج سرًّا مشتركًا 32 بايت يتّفق عليه الطرفان دون تبادله مباشرة.

السرّ الخامّ لا يُستعمَل مفتاحًا مباشرةً عادةً — مرّره عبر اشتق_مفتاح (HKDF) أوّلًا. فحص أمنيّ إلزاميّ (RFC 7748 §6.1): تبادل_مفتاح يرفض بخطأ صريح أيّ سرّ مشترك كلّه أصفار (ناتج ممكن عن مفاتيح عامّة خبيثة منخفضة الرتبة).

ولّد_مفتاح_خاص_توقيع / اشتق_مفتاح_عام_توقيع / وقّع / تحقق_توقيع — تواقيع Ed25519

متغير خاص = ولّد_مفتاح_خاص_توقيع()
متغير عام = اشتق_مفتاح_عام_توقيع(خاص)
متغير توقيع = وقّع("رسالة مهمّة", خاص)
اطبع_سطر(تحقق_توقيع("رسالة مهمّة", توقيع, عام))   # صحيح

توقيع رقميّ عبر Ed25519 (RFC 8032، مبنيّ على SHA-512 ذاتيّ التنفيذ):

  • ولّد_مفتاح_خاص_توقيع() — بذرة مفتاح خاصّ عشوائيّة جديدة.
  • اشتق_مفتاح_عام_توقيع(مفتاح_خاص) — المفتاح العامّ المقابل حتميًّا.
  • وقّع(رسالة، مفتاح_خاص) — توقيع حتميّ 64 بايت (لا عشوائيّة — نفس الرسالة والمفتاح يُنتجان دومًا نفس التوقيع).
  • تحقق_توقيع(رسالة، توقيع، مفتاح_عام)دالّة استعلام لا بوّابة: تُرجع صحيح/خطأ فقط، ولا ترمي استثناءً ولا تُنهي البرنامج على توقيع فاسد أو مدخل مشوَّه — الغرض أصلًا فحص مدخلات غير موثوقة بأمان.

ملاحظة تنفيذيّة (وحدة تشفير)

كل دوال وحدة تشفير مُنفَّذة ذاتيًّا (self-rolled، بلا OpenSSL/libsodium) داخل وقت التشغيل المشترك، ومُتحقَّقة كلّ واحدة مقابل شعاعات الاختبار الرسميّة لمعيارها (BLAKE3-team، RFC 2898/5869/7748/8032/8439/9106، ومقابل libargon2/hashlib بايثون لـأرجون2/اشتق_مفتاح_مرور).