في شرح GPG وOpenPGP تحدثنا عن الفكرة: المفتاح العام والخاص، والتشفير الهجين، والبصمة، وكيف تعرف أن المفتاح لصاحبه، ولماذا تحتاج تاريخ انتهاء وشهادة إلغاء. وفي هذا المقال سوف ننفذ كل ذلك بالأوامر، بحيث تخرج منه وأنت تملك مفتاحاً حديثاً بإعداد صحيح، وتعرف كيف تتبادله مع غيرك وتتحقق من مفاتيحهم، وتشفر وتوقع، وتوقع Git Commits، وتتحقق من ملف نزلته من الإنترنت، وتعرف ماذا تفعل عندما يظهر لك خطأ من أخطاء GPG المشهورة. وسوف نتناول في هذا المقال ما يلي:
- تثبيت GPG على Linux وmacOS وWindows.
- إنشاء مفتاح ed25519 بمفتاح تشفير فرعي cv25519 وتاريخ انتهاء، وشهادة الإلغاء.
- تصدير المفتاح العام ونشره على keys.openpgp.org وعلى نطاقك عبر WKD.
- استيراد مفتاح شخص آخر والتحقق من بصمته، ثم التشفير وفك التشفير والتوقيع والتحقق.
- تشفير البريد في Thunderbird، وتوقيع Git Commits والوسوم Tags.
- التحقق من ملف منزل بمثال حقيقي من Debian.
- النسخ الاحتياطي ونقل المفتاح إلى جهاز جديد، وتمديد تاريخ الانتهاء، والإلغاء، ومفاتيح الأمان مثل YubiKey.
- الأخطاء الشائعة وحلولها، وجدول بالأوامر.
التجربة: Alice وBob في Container واحد
حتى تكون كل المخرجات في هذا المقال حقيقية دون أن نلمس مفاتيح أي شخص حقيقي، شغلنا التجربة كلها في Container مؤقت من Debian 13.7 فيه GnuPG، ولكل شخصية وهمية مجلد GPG خاص بها يحدده المتغير GNUPGHOME، كأن كل مجلد جهاز مستقل، والملفات تنتقل بينهم عبر مجلد مشترك يقوم مقام البريد. والصورة التالية تبين ترتيب التجربة:

والملف Dockerfile الذي بنينا منه ال Image هو التالي:
FROM debian:13.7-slim
RUN apt-get update && apt-get install -y --no-install-recommends gnupg git curl ca-certificates dirmngr gpg-wks-client pinentry-curses && rm -rf /var/lib/apt/lists/*ثم بنيناه وشغلناه، وكل أمر في بقية المقال نفذناه داخله عبر docker exec مع المتغير GNUPGHOME للشخصية المطلوبة:
docker build -t lab-gpg-debian:13.7 .
docker run -d --rm --name lab-gpg-box -w /lab lab-gpg-debian:13.7 sleep infinity
docker exec lab-gpg-box sh -c 'mkdir -p -m 700 /lab/alice /lab/bob /lab/carol /lab/alice-laptop; mkdir -p /lab/shared'
docker exec -it -e GNUPGHOME=/lab/alice lab-gpg-box bashولاحظ نقطة مهمة قبل أن نبدأ: كل أمر يستخدم المفتاح الخاص يطلب كلمة المرور Passphrase عبر برنامج صغير اسمه pinentry، يظهر لك نافذة أو مربعاً في الطرفية. ولأننا شغلنا الأوامر آلياً أضفنا لهذه الأوامر الخيارات --batch --pinentry-mode loopback --passphrase "..." حتى تمرر كلمة المرور مباشرة، وتركناها في الأوامر كما نفذناها. أما على جهازك فلا تضعها أبداً، لأن كلمة المرور سوف تحفظ في سجل الأوامر Shell History، فاحذفها واترك pinentry يسألك.
تثبيت GPG على Linux وmacOS وWindows
- Linux: GnuPG موجود في كل التوزيعات، وفي Debian وUbuntu تثبته بالأمر
sudo apt install gnupg، وفي Fedora وRHEL بالأمرsudo dnf install gnupg2. والإصدار الذي يأتي مع التوزيعة المستقرة غالباً أقدم من الإصدار الحالي، ففي Debian 13 الإصدار 2.4.7، بينما الإصدار المستقر الحالي من المشروع 2.5.24 بحسب صفحة التنزيل، وكل ما في هذا المقال يعمل على الاثنين. - macOS: أمامك طريقتان: الأولى
brew install gnupgمن Homebrew، وبحسب صفحة الحزمة فالإصدار فيه 2.5.24 برخصة GPL-3.0-or-later، والثانية GPG Suite الذي يضيف واجهة رسومية لإدارة المفاتيح هي GPG Keychain، وهي مجانية، أما إضافة البريد GPG Mail لبرنامج Mail من Apple فتحتاج اشتراكاً مدفوعاً Support Plan. - Windows: Gpg4win، وآخر إصدار منه 5.1.1 بتاريخ 23 سبتمبر 2026، وهو برنامج حر مجاني وأغلب مكوناته برخصة GNU GPL، ويأتي مع Kleopatra لإدارة المفاتيح والشهادات من واجهة رسومية، وGpgOL لبرنامج Outlook، وGpgEX لقائمة الملفات في Explorer. وبعد التثبيت يعمل الأمر
gpgنفسه من PowerShell.
وتأكد من الإصدار بعد التثبيت، والمخرج في التجربة سوف يكون كما يلي:
$ gpg --version | head -3
gpg (GnuPG) 2.4.7
libgcrypt 1.11.0
Copyright (C) 2024 g10 Code GmbHإنشاء المفتاح
الطريقة التفاعلية هي الأمر gpg --full-generate-key، وهو يسألك عن نوع المفتاح ومدته والاسم والبريد وكلمة المرور خطوة خطوة. ولكننا نفضل الأمر --quick-gen-key لأنه يجعلك تحدد كل شيء صراحة في سطر واحد، فنبدأ بالمفتاح الرئيسي من نوع ed25519 بصلاحيتي التوقيع وشهادة المفاتيح، ومدته سنتان:
gpg --batch --pinentry-mode loopback --passphrase "alice-lab-pass" \
--quick-gen-key "Alice Example <[email protected]>" ed25519 sign,cert 2yوالمخرج سوف يكون كما يلي:
gpg: keybox '/lab/alice/pubring.kbx' created
gpg: /lab/alice/trustdb.gpg: trustdb created
gpg: directory '/lab/alice/openpgp-revocs.d' created
gpg: revocation certificate stored as '/lab/alice/openpgp-revocs.d/F8E558CDCE839C89D465E692C285B11B1C262E80.rev'ثم نضيف المفتاح الفرعي للتشفير من نوع cv25519 بالمدة نفسها، ونستخدم البصمة الكاملة للإشارة إلى المفتاح:
gpg --batch --pinentry-mode loopback --passphrase "alice-lab-pass" \
--quick-add-key F8E558CDCE839C89D465E692C285B11B1C262E80 cv25519 encr 2y
gpg --list-secret-keys --keyid-format long --with-subkey-fingerprintsوالمخرج سوف يكون كما يلي:
/lab/alice/pubring.kbx
----------------------
sec ed25519/C285B11B1C262E80 2026-10-09 [SC] [expires: 2028-10-08]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid [ultimate] Alice Example <[email protected]>
ssb cv25519/7220124A948A4F79 2026-10-09 [E] [expires: 2028-10-08]
099269D99FFC137AB5C7B9077220124A948A4F79في الإعداد أعلاه لاحظ التالي:
secهو المفتاح الرئيسي وصلاحياته[SC]، وssbهو المفتاح الفرعي للتشفير[E]، ولكل منهما تاريخ انتهاء بعد سنتين.- الكلمة
[ultimate]تعني أن GPG يثق بهذا المفتاح ثقة كاملة لأنه مفتاحك أنت. - لم نستخدم RSA، فمفاتيح ed25519 وcv25519 أصغر وأسرع، وهي الافتراضية في GnuPG الحديث، ومدعومة في كل البرامج المنتشرة اليوم.
وقد يتساءل البعض: لماذا لا نستخدم الكلمة default ونريح أنفسنا؟ والإجابة في مفتاح Bob، فقد أنشأناه بالأمر المختصر --quick-gen-key "Bob Example <[email protected]>" default default 2y، والنتيجة كانت كما يلي:
$ gpg -k --keyid-format long [email protected]
pub ed25519/E60C7D75F408B810 2026-10-09 [SC] [expires: 2028-10-08]
53C672A060A5A2FE6B3A7F80E60C7D75F408B810
uid [ultimate] Bob Example <[email protected]>
sub cv25519/380BCF94EF97A3CC 2026-10-09 [E]لاحظ أن الأنواع صحيحة، ولكن المفتاح الفرعي للتشفير بلا تاريخ انتهاء، لأن المدة في هذا الأمر طبقت على المفتاح الرئيسي فقط. وهذا ليس كارثة، لأن انتهاء المفتاح الرئيسي يوقف المفتاح كله، ولكنه سبب كاف لتحدد كل جزء بنفسك وتنظر إلى المخرج بعد كل إنشاء.
وأما كلمة المرور فهي تحمي المفتاح الخاص على القرص، فإذا سرق الملف لم يستطع السارق استخدامه دونها، فاختر كلمة طويلة، والأفضل جملة من عدة كلمات، واحفظها في مدير كلمات المرور.
شهادة الإلغاء: جهزها اليوم
كما رأيت في المخرج السابق، أنشأ GnuPG شهادة إلغاء تلقائياً في المجلد openpgp-revocs.d، وهذا أول ما فيها:
$ cat /lab/alice/openpgp-revocs.d/F8E558CDCE839C89D465E692C285B11B1C262E80.rev | head -20
This is a revocation certificate for the OpenPGP key:
pub ed25519 2026-10-09 [SC] [expires: 2028-10-08]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid Alice Example <[email protected]>
A revocation certificate is a kind of "kill switch" to publicly
declare that a key shall not anymore be used. It is not possible
to retract such a revocation certificate once it has been published.
Use it to revoke this key in case of a compromise or loss of
the secret key. However, if the secret key is still accessible,
it is better to generate a new revocation certificate and give
a reason for the revocation. For details see the description of
of the gpg command "--generate-revocation" in the GnuPG manual.
To avoid an accidental use of this file, a colon has been inserted
before the 5 dashes below. Remove this colon with a text editor
before importing and publishing this revocation certificate.وإذا أردت شهادة فيها سبب الإلغاء وتعليق يقرؤه الناس، فالأمر --gen-revoke يسألك عنهما، وهذه الجلسة كاملة من التجربة:
$ gpg --pinentry-mode loopback --passphrase alice-lab-pass --output alice-revoke.asc --gen-revoke [email protected]
sec ed25519/C285B11B1C262E80 2026-10-09 Alice Example <[email protected]>
Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
> Key stored on the old laptop
>
Reason for revocation: Key has been compromised
Key stored on the old laptop
Is this okay? (y/N) y
ASCII armored output forced.
Revocation certificate created.
Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable. But have some caution: The print system of
your machine might store the data and make it available to others!انقل هذا الملف، والملف التلقائي أيضاً، إلى مكان بعيد عن الجهاز مثل ذاكرة USB في درج مقفل أو ورقة مطبوعة، والسبب أن من يحصل عليها يستطيع أن يلغي مفتاحك، وأن الجهاز نفسه هو ما قد تفقده.
تصدير المفتاح العام ونشره
المفتاح العام تصدره بالأمر --export، والخيار --armor يجعله نصاً يمكن لصقه في رسالة أو صفحة:
$ gpg --armor --export [email protected] > alice.asc
$ head -3 alice.asc; wc -c alice.asc
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEasjnfhYJKwYBBAHaRw8BAQdA0N/HWbcFA63TumW2ecVgBvP5xYEbaqcgdNna
660 alice.ascولاحظ أن المفتاح كاملاً 660 بايت فقط، وهذا من مزايا ed25519. وبعد ذلك أمامك ثلاث طرق لنشره، وكلها شرحنا فكرتها في قسم الثقة في مقال الشرح:
- أرسله مباشرة إلى من يحتاجه، مع البصمة عبر قناة أخرى.
انشره على نطاقك عبر WKD إذا كان لك نطاق وبريد عليه، فيجده أي برنامج من عنوان البريد وحده. والأداة gpg-wks-client تحسب المسار وتنشئ المجلدات، وفي Debian تجدها في /usr/lib/gnupg/ وليست في المسار الافتراضي:
$ /usr/lib/gnupg/gpg-wks-client --print-wkd-hash [email protected]
kei1q4tipxxu1yj79k9kfukdhfy631xe [email protected]
$ /usr/lib/gnupg/gpg-wks-client --print-wkd-url [email protected]
https://openpgpkey.example.test/.well-known/openpgpkey/example.test/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe?l=alice
$ mkdir -p openpgpkey/example.test
$ /usr/lib/gnupg/gpg-wks-client --install-key -C openpgpkey F8E558CDCE839C89D465E692C285B11B1C262E80 [email protected]
gpg-wks-client: key F8E558CDCE839C89D465E692C285B11B1C262E80 published for '[email protected]'
$ find openpgpkey | sort
openpgpkey
openpgpkey/example.test
openpgpkey/example.test/hu
openpgpkey/example.test/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe
openpgpkey/example.test/policyفي الإعداد أعلاه لاحظ أن اسم الملف هو هاش الجزء الأول من البريد بترميز Z-Base-32 كما تحدده مسودة WKD، وأن المجلد الناتج تضعه كما هو تحت /.well-known/ في سيرفر الويب للنطاق الفرعي openpgpkey، وهي الطريقة المتقدمة Advanced Method، أو مباشرة على النطاق الرئيسي في الطريقة المباشرة Direct Method مع مسار دون اسم النطاق.
ارفعه إلى keys.openpgp.org بالأمر التالي، ثم افتح الرسالة التي تصلك وأكد البريد، فبدون هذا التأكيد لن يظهر اسمك وبريدك لمن يبحث عنك، كما يشرح دليل السيرفر. ولم ننفذ هذا الأمر في التجربة، لأن السيرفر عام ولا مكان فيه لمفاتيح تجريبية:
gpg --keyserver hkps://keys.openpgp.org --send-keys F8E558CDCE839C89D465E692C285B11B1C262E80استيراد مفتاح غيرك والتحقق من بصمته
الآن ننتقل إلى Bob، وصله ملف alice.asc فاستورده ثم عرض بصمته:
$ gpg --import /lab/shared/alice.asc
gpg: key C285B11B1C262E80: public key "Alice Example <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1
$ gpg --fingerprint [email protected]
pub ed25519 2026-10-09 [SC] [expires: 2028-10-08]
F8E5 58CD CE83 9C89 D465 E692 C285 B11B 1C26 2E80
uid [ unknown] Alice Example <[email protected]>
sub cv25519 2026-10-09 [E] [expires: 2028-10-08]لاحظ الكلمة [ unknown]: المفتاح موجود عند Bob، ولكن GPG لا يعرف هل هو لAlice فعلاً. ولو حاول Bob أن يشفر لها الآن في الوضع الآلي فسوف يرفض GPG:
$ gpg --batch --armor --encrypt --recipient [email protected] report.txt
gpg: 7220124A948A4F79: There is no assurance this key belongs to the named user
gpg: report.txt: encryption failed: Unusable public keyوالحل الصحيح ليس أن تجبره، وإنما أن تتحقق: يتصل Bob بAlice، أو يقابلها، وتقرأ له بصمتها من جهازها، فإذا طابقت البصمة التي عنده، يوقع على مفتاحها توقيعاً محلياً Local Signature لا يخرج من جهازه، ومعناه «أنا تحققت من هذا المفتاح بنفسي»:
$ gpg --batch --pinentry-mode loopback --passphrase bob-lab-pass --quick-lsign-key F8E558CDCE839C89D465E692C285B11B1C262E80
pub ed25519/C285B11B1C262E80
created: 2026-10-09 expires: 2028-10-08 usage: SC
trust: unknown validity: unknown
Primary key fingerprint: F8E5 58CD CE83 9C89 D465 E692 C285 B11B 1C26 2E80
Alice Example <[email protected]>
This key is due to expire on 2028-10-08.
The signature will be marked as non-exportable.
$ gpg -k [email protected]
pub ed25519 2026-10-09 [SC] [expires: 2028-10-08]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid [ full ] Alice Example <[email protected]>
sub cv25519 2026-10-09 [E] [expires: 2028-10-08]صارت الصلاحية [ full ]، ومن الآن يقبل GPG التشفير لهذا المفتاح. والفرق بين --quick-lsign-key و--quick-sign-key أن الثاني توقيع قابل للتصدير يراه الآخرون إذا نشرت مفتاح Alice بعد توقيعك، وهذا ما كان يستخدم في شبكة الثقة، أما المحلي فيكفيك أنت ولا يكشف علاقتك بأحد.
تشفير الملفات وفك تشفيرها
يشفر Bob ملفاً لAlice بالأمر --encrypt مع --recipient، والخيار --armor يجعل الناتج نصاً يمكن لصقه في رسالة:
$ printf "Q3 budget: 120k\nMeeting moved to Sunday.\n" > report.txt
$ gpg --armor --encrypt --recipient [email protected] report.txt
$ cat report.txt.asc
-----BEGIN PGP MESSAGE-----
hF4DciASSpSKT3kSAQdAc4TN4vf7R5hMfXc7fvHwv/Sfg37s/eAArlFMDdcotj0w
PuGmOF6ta7bYVTje5bz7zZbXLFYHpaf+/LuqUG3/U97TIGRU4Nf/jKtk/U6kRoks
0m4Bp51wbULIpWodjv2uTDllpgnCT53Qe8PscMOqhF5DS4dVupi8s513Y0EofsWh
QRfAMdl3wblDg2h34vEaPh6i4B1FqJPE383a4SzCKek4KvmnbNKxZzrNudvwbljy
rLkSvwmECO0vBgm+Cnpa0g==
=4cdN
-----END PGP MESSAGE-----وتفكه Alice بالأمر --decrypt، والمخرج سوف يكون كما يلي:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --decrypt /lab/shared/report.txt.asc
gpg: encrypted with cv25519 key, ID 7220124A948A4F79, created 2026-10-09
"Alice Example <[email protected]>"
Q3 budget: 120k
Meeting moved to Sunday.ولاحظ أن Bob لا يستطيع أن يفك الملف الذي شفره بنفسه، لأنه شفره لمفتاح Alice فقط، فإذا أردت أن تحتفظ بنسخة تقرؤها أنت أيضاً فأضف نفسك مستلماً ثانياً --recipient [email protected]، أو ضع في ملف الإعداد gpg.conf السطر encrypt-to مع بصمتك.
وفي الغالب تريد أن تشفر وتوقع معاً، حتى يعرف المستلم أن الرسالة منك وليست من أي شخص يملك مفتاحه العام، وهذا مثال من Alice إلى Bob بعد أن تحققت من مفتاحه:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --sign --encrypt --armor -r [email protected] reply.txtوعند Bob يظهر النص ثم نتيجة التحقق من التوقيع:
$ gpg --batch --pinentry-mode loopback --passphrase bob-lab-pass --decrypt /lab/shared/reply.txt.asc
gpg: encrypted with cv25519 key, ID 380BCF94EF97A3CC, created 2026-10-09
"Bob Example <[email protected]>"
The new VPN password is in the vault.
gpg: Signature made Fri Oct 9 13:12:31 2026 UTC
gpg: using EDDSA key F8E558CDCE839C89D465E692C285B11B1C262E80
gpg: Good signature from "Alice Example <[email protected]>" [full]توقيع الملفات والتحقق منها
للتوقيع ثلاثة أشكال، ولكل منها استخدام:
- التوقيع المنفصل Detached Signature بالأمر
--detach-sign: ملف توقيع مستقل بجانب الملف الأصلي، وهو الشكل المستخدم في ملفات الإصدارات، لأن الملف الأصلي يبقى كما هو. - التوقيع المقروء Clearsign بالأمر
--clearsign: النص يبقى مقروءاً وحوله التوقيع، وهو مناسب لإعلان أو رسالة نصية، وهو شكل ملفInReleaseفي مستودعات Debian. - التوقيع المدمج بالأمر
--sign: الملف والتوقيع في ملف واحد مضغوط غير مقروء، وهو الأقل استخداماً اليوم.
توقع Alice ملف ملاحظات إصدار توقيعاً منفصلاً:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --armor --detach-sign release-notes.txt
$ ls -l release-notes.txt*
-rw-r--r-- 1 root root 45 Oct 9 13:11 release-notes.txt
-rw-r--r-- 1 root root 228 Oct 9 13:11 release-notes.txt.asc
$ cat release-notes.txt.asc
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQT45VjNzoOcidRl5pLChbEbHCYugAUCasjoGQAKCRDChbEbHCYu
gKMCAP9cFdQjf0PPFFNUGXMs+eHUmpviitnkvAN4UlpYQYe3lgD/VtmXjGhL72A4
U/Xa1lhd9JYJK65KwSYEdpZJDRq5vAY=
=ITzN
-----END PGP SIGNATURE-----ويتحقق Bob منه، ثم يغير حرفاً في الملف ويتحقق مرة أخرى:
$ gpg --verify release-notes.txt.asc release-notes.txt
gpg: Signature made Fri Oct 9 13:11:53 2026 UTC
gpg: using EDDSA key F8E558CDCE839C89D465E692C285B11B1C262E80
gpg: Good signature from "Alice Example <[email protected]>" [full]
$ sed -i "s/v1.4.0/v1.4.1/" release-notes.txt
$ gpg --verify release-notes.txt.asc release-notes.txt
gpg: Signature made Fri Oct 9 13:11:53 2026 UTC
gpg: using EDDSA key F8E558CDCE839C89D465E692C285B11B1C262E80
gpg: BAD signature from "Alice Example <[email protected]>" [full]وفي السكربتات لا تقرأ النص، وإنما رمز الخروج Exit Code: الأمر gpg --verify أعاد 0 في الحالة الأولى و1 في الحالة الثانية في تجربتنا. وانتبه أن رمز 0 يعني أن التوقيع سليم من أي مفتاح موجود في حلقة مفاتيحك، فالسكربت الآمن يتحقق بحلقة مفاتيح لا يوجد فيها إلا المفتاح المتوقع، كما سنرى في قسم التحقق من ملف منزل.
وأما التوقيع المقروء فهذا شكله:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --clearsign notice.txt
$ cat notice.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
We moved the backup window to 02:00.
-----BEGIN PGP SIGNATURE-----
iHUEARYKAB0WIQT45VjNzoOcidRl5pLChbEbHCYugAUCasjoLQAKCRDChbEbHCYu
gCUJAQCPWXr6cI0ojuDQLmlYAV7vRlssQaOfsYNnfaqIIwa9jgEA8U88o7qmLSgu
y4j3weTDYGDZl25azGp2aISmySloogk=
=9yqp
-----END PGP SIGNATURE-----ويتحقق منه Bob بالأمر gpg --verify notice.txt.asc دون ملف ثان، لأن النص داخله.
تشفير البريد في Thunderbird
منذ الإصدار 78 في عام 2020 صار دعم OpenPGP مدمجاً في Thunderbird عبر مكتبة RNP، فلا تحتاج أن تثبت GnuPG ولا إضافة Enigmail القديمة. والخطوات باختصار:
- افتح إعدادات الحساب Account Settings، ثم القسم End-To-End Encryption.
- أنشئ مفتاحاً جديداً من هناك، أو استورد مفتاحك الذي أنشأته بـ GPG بعد تصديره بالأمر
gpg --armor --export-secret-keysكما سيأتي في قسم النسخ الاحتياطي. - استورد المفاتيح العامة لمن تراسلهم، وغير حالة كل مفتاح إلى «Accepted (verified)» بعد أن تقارن البصمة معه، فهذا هو المقابل لما فعلناه بالأمر
--quick-lsign-key. - عند كتابة رسالة فعل التشفير من زر Encrypt في نافذة الكتابة.
ولاحظ أن Thunderbird يحفظ المفاتيح في مخزنه الخاص وليس في GnuPG، لذلك إذا كانت مفاتيحك الخاصة على بطاقة ذكية أو YubiKey فعليك أن تفعل الخيار mail.openpgp.allow_external_gnupg من محرر الإعدادات المتقدمة، كما يشرح دليل البطاقات الذكية في Thunderbird، حتى يستخدم GnuPG المثبت على جهازك عند الحاجة. وبحسب صفحة الحالة فإن Thunderbird يشفر عنوان الرسالة Subject افتراضياً، ولكن بقية الترويسات تبقى ظاهرة كما شرحنا في مقال الشرح. ولم نثبت Thunderbird في هذه التجربة، فهذه الخطوات من توثيقه.
توقيع Git Commits والوسوم
اسم الكاتب وبريده في ال Commit مجرد نص، وأي شخص يستطيع أن يكتب اسمك، وهذا ما فعله Bob في تجربتنا على نسخة من مستودع Alice:
$ git -c user.name="Alice Example" -c [email protected] commit -q -am "Fix typo"
$ git log --format="%h %an <%ae> %G? %s"
7af029f Alice Example <[email protected]> N Fix typo
f728666 Alice Example <[email protected]> G Add READMEالحرف بعد البريد هو حالة التوقيع من %G?: الحرف G يعني توقيعاً سليماً، وN يعني أنه لا يوجد توقيع. فال Commit الأول كتبته Alice ووقعته، والثاني كتبه Bob باسمها وفيه سطر يحمل كوداً من موقع خارجي، والفرق الوحيد الظاهر بينهما هو التوقيع. وإعداد التوقيع عند Alice كان كما يلي:
git config user.name "Alice Example"
git config user.email [email protected]
git config user.signingkey F8E558CDCE839C89D465E692C285B11B1C262E80
git config commit.gpgsign true
git config tag.gpgSign trueفي الإعداد أعلاه لاحظ التالي:
user.signingkeyيحدد المفتاح بالبصمة الكاملة، وبحسب توثيق git-config فهذه القيمة تمرر كما هي إلى الخيار--local-userفي gpg.commit.gpgsignوtag.gpgSignيجعلان كل Commit وكل وسم موقعاً دون أن تكتب-Sكل مرة.- البريد في
user.emailيجب أن يطابق بريداً في مفتاحك، لأن منصات مثل GitHub لا تعرض علامة Verified إلا إذا تطابق، وعليك أن ترفع مفتاحك العام إلى حسابك فيها. - في التجربة فقط أضفنا
gpg.programيشير إلى سكربت صغير يمرر كلمة المرور، لأن Git كان يعمل دون طرفية، وعلى جهازك لا تحتاجه.
ثم أنشأت Alice Commit ووسماً، وتحققت منهما:
$ git commit -q -m "Add README"
$ git tag -m "first release" v0.1.0
$ git log --show-signature -1
commit f7286661542d5f269e9d0719e0d81919232899ea
gpg: Signature made Fri Oct 9 13:12:51 2026 UTC
gpg: using EDDSA key F8E558CDCE839C89D465E692C285B11B1C262E80
gpg: Good signature from "Alice Example <[email protected]>" [ultimate]
Author: Alice Example <[email protected]>
Date: Fri Oct 9 13:12:51 2026 +0000
Add README
$ git verify-tag v0.1.0
gpg: Signature made Fri Oct 9 13:12:51 2026 UTC
gpg: using EDDSA key F8E558CDCE839C89D465E692C285B11B1C262E80
gpg: Good signature from "Alice Example <[email protected]>" [ultimate]وقد يتساءل البعض: لماذا لا أوقع بمفتاح SSH الذي أستخدمه أصلاً للدفع إلى المستودع؟ والإجابة أن هذا ممكن منذ أن أضاف Git القيمة ssh للإعداد gpg.format، وقد ذكرناه مع مفاتيح الأمان في مقال Passkeys، والمقارنة الكاملة بين الطريقتين ومتى تختار كلاً منهما موضوع مقال قادم بإذن الله في مرحلة Git من خارطة الطريق.
التحقق من ملف منزل: مثال Debian
هذا هو الاستخدام الذي سوف تحتاجه أكثر من أي شيء آخر، والصورة التالية تبين خطواته:

نزل Bob قائمة الهاش وتوقيعها لملفات Debian 13.7، وحاول التحقق قبل أن يملك المفتاح:
$ curl -sSfLO https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS
$ curl -sSfLO https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS.sign
$ cat SHA256SUMS
a7ef94ac2fb9a7fec454552abd629b7cc9d5155c886165a45649f5ce6167e355 debian-13.7.0-amd64-netinst.iso
d33ed0c64bde5ff43445c0c530f9da599954d8585771c55345cb840d7997d4a7 debian-edu-13.7.0-amd64-netinst.iso
d6d4e0d038936230229a66b7c1765452e73c72a962e79dbb99544882295271e8 debian-mac-13.7.0-amd64-netinst.iso
$ gpg --verify SHA256SUMS.sign SHA256SUMS
gpg: Signature made Sat Sep 12 16:20:46 2026 UTC
gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Can't check signature: No public keyالخطأ No public key هنا طبيعي، ومعناه أن التوقيع من مفتاح بصمته DF9B9C49... وهو غير موجود عند Bob. والخطأ الذي يقع فيه كثيرون أن يبحثوا عن هذه البصمة في سيرفر مفاتيح ويستوردوا أول نتيجة، والصحيح أن تأخذ المفتاح من مصدر رسمي تعرفه، وهنا صفحة التحقق في موقع Debian التي تكتب البصمات كاملة وتضع رابطاً لكل مفتاح:
$ curl -sSfL -o debian-cd-key.asc https://www.debian.org/CD/key-DA87E80D6294BE9B.txt
$ gpg --show-keys --fingerprint debian-cd-key.asc
pub rsa4096 2011-01-05 [SC]
DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B
uid Debian CD signing key <[email protected]>
sub rsa4096 2011-01-05 [E]الأمر --show-keys يعرض المفتاح دون أن يستورده، فتقارن البصمة DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B بالمكتوبة في الصفحة، وقد طابقت، ثم تستورده وتتحقق:
$ gpg --import debian-cd-key.asc
$ gpg --verify SHA256SUMS.sign SHA256SUMS
gpg: Signature made Sat Sep 12 16:20:46 2026 UTC
gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Good signature from "Debian CD signing key <[email protected]>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9Bوالتحذير هنا متوقع، لأنك لم توقع على مفتاح Debian، والمهم أن البصمة في آخر سطر هي نفسها التي تحققت منها من الصفحة الرسمية. وبعد ذلك تبقى الخطوة الأخيرة التي ينساها كثيرون: أن تقارن هاش ملف ISO الذي نزلته بالقائمة الموقعة، بالأمر sha256sum -c SHA256SUMS --ignore-missing في المجلد الذي فيه الملف، فالتوقيع يحمي القائمة فقط. ولم ننزل ملف ISO نفسه في التجربة لأن الفكرة واضحة دونه.
وفي السكربتات والخطوط الآلية لا تستخدم حلقة مفاتيحك الشخصية، وإنما أداة تتحقق بحلقة مفاتيح فيها المفتاح المتوقع وحده، فإذا كان التوقيع من أي مفتاح آخر فشل التحقق. والأداة التقليدية لهذا هي gpgv، ولكنها لم تكن مثبتة في Container التجربة من Debian 13 رغم تثبيت gnupg، بينما كانت sqv موجودة لأن apt نفسه يعتمد عليها، فاستخدمناها مع ملف المفتاح بالصيغة الثنائية:
$ gpg --dearmor < debian-cd-key.asc > debian-cd.gpg
$ sqv --keyring debian-cd.gpg SHA256SUMS.sign SHA256SUMS
DF9B9C49EAA9298432589D76DA87E80D6294BE9B
$ echo $?
0
$ sed -i "s/^a7ef/b7ef/" SHA256SUMS
$ sqv --keyring debian-cd.gpg SHA256SUMS.sign SHA256SUMS
Verifying signature:
Message has been manipulated
$ echo $?
1لاحظ أن sqv يطبع بصمة المفتاح الذي وقع عند النجاح ويعيد 0، ويرفض القائمة التي غيرنا فيها حرفاً واحداً ويعيد 1، وهذا كل ما يحتاجه سكربت.
النسخ الاحتياطي ونقل المفتاح إلى جهاز جديد
إذا ضاع المفتاح الخاص دون نسخة احتياطية فلن تستطيع فك أي رسالة شفرت لك به، أبداً، فلا يوجد «نسيت كلمة المرور» في GPG. والنسخة الاحتياطية تتكون من ملفين: المفتاح الخاص مع كل أجزائه، وقاعدة الثقة Owner Trust التي تحفظ ثقتك بالمفاتيح:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --armor --export-secret-keys [email protected] > alice-secret.asc
$ gpg --export-ownertrust > alice-ownertrust.txt
$ head -2 alice-secret.asc
-----BEGIN PGP PRIVATE KEY BLOCK-----
$ cat alice-ownertrust.txt
# List of assigned trustvalues, created Fri Oct 9 13:13:54 2026 UTC
# (Use "gpg --import-ownertrust" to restore them)
F8E558CDCE839C89D465E692C285B11B1C262E80:6:والمفتاح الخاص في الملف المصدر يبقى محمياً بكلمة المرور نفسها، ومع ذلك عامله كأثمن ملف تملكه: لا ترفعه إلى خدمة تخزين سحابية دون تشفير إضافي، ولا ترسله بالبريد. ثم على الجهاز الجديد، وهو المجلد alice-laptop في تجربتنا:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --import /lab/shared/alice-secret.asc
gpg: keybox '/lab/alice-laptop/pubring.kbx' created
gpg: /lab/alice-laptop/trustdb.gpg: trustdb created
gpg: key C285B11B1C262E80: public key "Alice Example <[email protected]>" imported
gpg: key C285B11B1C262E80: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
$ gpg --import-ownertrust /lab/shared/alice-ownertrust.txt
gpg: inserting ownertrust of 6
$ gpg -K
/lab/alice-laptop/pubring.kbx
-----------------------------
sec ed25519 2026-10-09 [SC] [expires: 2028-10-08]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid [ultimate] Alice Example <[email protected]>
ssb cv25519 2026-10-09 [E] [expires: 2028-10-08]ظهر المفتاح الخاص sec والمفتاح الفرعي ssb بالبصمة نفسها، والثقة [ultimate] عادت كما كانت. ولا تنقل المجلد ~/.gnupg كاملاً بين أنظمة مختلفة، لأن فيه ملفات Sockets وإعدادات خاصة بالجهاز، والتصدير والاستيراد هما الطريقة الآمنة.
تمديد تاريخ الانتهاء
قبل أن يقترب تاريخ الانتهاء تمدده للمفتاح الرئيسي ثم للمفاتيح الفرعية، والنجمة "*" تعني كل المفاتيح الفرعية:
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --quick-set-expire F8E558CDCE839C89D465E692C285B11B1C262E80 3y
$ gpg --batch --pinentry-mode loopback --passphrase alice-lab-pass --quick-set-expire F8E558CDCE839C89D465E692C285B11B1C262E80 3y "*"
$ gpg -k [email protected]
pub ed25519 2026-10-09 [SC] [expires: 2029-10-08]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid [ultimate] Alice Example <[email protected]>
sub cv25519 2026-10-09 [E] [expires: 2029-10-08]ولاحظ أن المدة تحسب من تاريخ اليوم وليس من التاريخ القديم، فصار الانتهاء في 2029. والتمديد لا يفيد الآخرين حتى يحصلوا على النسخة الجديدة من مفتاحك العام، فتصدره مرة أخرى وتنشره، وعندما استوردها Bob ظهر له أنها توقيعات جديدة على المفتاح نفسه:
$ gpg --import /lab/shared/alice.asc
gpg: key C285B11B1C262E80: "Alice Example <[email protected]>" 2 new signatures
gpg: Total number processed: 1
gpg: new signatures: 2إلغاء المفتاح عند سرقته أو فقده
إذا سرق الجهاز أو شككت أن المفتاح الخاص تسرب، فاستورد شهادة الإلغاء في حلقة مفاتيحك ثم انشر المفتاح الملغى بالطريقة نفسها التي نشرته بها. وفي تجربتنا استوردت Carol الشهادة التي أعدتها Alice مسبقاً:
$ gpg --import /lab/shared/alice-revoke.asc
gpg: key C285B11B1C262E80: "Alice Example <[email protected]>" revocation certificate imported
gpg: Total number processed: 1
gpg: new key revocations: 1
$ gpg -k [email protected]
pub ed25519 2026-10-09 [SC] [revoked: 2026-10-09]
F8E558CDCE839C89D465E692C285B11B1C262E80
uid [ revoked] Alice Example <[email protected]>
$ gpg --auto-key-locate local --encrypt -r [email protected] -o /dev/null /lab/shared/release-notes.txt
gpg: [email protected]: skipped: No public key
gpg: /lab/shared/release-notes.txt: encryption failed: No public keyومن الآن ترفض Carol التشفير لهذا المفتاح، وأي توقيع قديم منه يظهر معه تحذير الإلغاء والسبب، كما رأينا في مقال الشرح. وإذا كان المفتاح على keys.openpgp.org فارفع النسخة الملغاة بالأمر --send-keys نفسه الذي رفعته به، وإذا كان على WKD فاستبدل الملف في المجلد بالنسخة الملغاة.
مفاتيح الأمان YubiKey والبطاقات الذكية
أقوى حماية للمفتاح الخاص ألا يكون على القرص أصلاً، فمفاتيح الأمان التي تدعم OpenPGP، مثل YubiKey وNitrokey، تحفظ المفاتيح الفرعية داخل شريحة لا تسمح بتصديرها، ويتم التوقيع وفك التشفير داخل المفتاح نفسه بعد أن تكتب رقمه السري PIN. والطريقة الشائعة أن تنشئ المفتاح على جهاز آمن، وتأخذ منه نسخة احتياطية كما في القسم السابق، ثم تنقل المفاتيح الفرعية إلى البطاقة بالأمر gpg --edit-key ثم الأمر keytocard داخله، وتبقى البطاقة عندك كمفتاح البيت. وأوامر البطاقة تمر عبر برنامج scdaemon، فإذا لم يكن مثبتاً أو لم تكن البطاقة موصولة فسوف ترى رسالة مثل التي ظهرت في Container التجربة، الذي لم نثبت فيه هذا البرنامج ولم نصل به أي جهاز:
$ gpg --card-status
gpg: error getting version from 'scdaemon': No SmartCard daemon
gpg: OpenPGP card not available: No SmartCard daemonوفي Debian وUbuntu تثبت البرنامج بالحزمة scdaemon. وقد شرحنا الفرق بين طرازات مفاتيح الأمان وما يدعمه كل منها في مقال Passkeys، وانتبه عند الشراء أن السلسلة التي تدعم FIDO فقط من بعض الشركات لا تدعم OpenPGP.
الأخطاء الشائعة وكيف تقرؤها
وفيما يلي الأخطاء التي ظهرت لنا في التجربة، وكلها رسائل حقيقية:
Can't check signature: No public keyعند التحقق: المفتاح الذي وقع غير موجود عندك، فخذ البصمة من سطرusing RSA keyوابحث عن المفتاح في المصدر الرسمي للمشروع، ولا تستورد أول نتيجة من سيرفر مفاتيح.There is no assurance this key belongs to the named userثمUnusable public keyعند التشفير: المفتاح موجود ولكنك لم تتحقق منه، فقارن البصمة مع صاحبها ثم وقعه بالأمر--quick-lsign-key. ولا تستخدم--trust-model alwaysلتتجاوزه، لأنك بهذا تلغي الحماية الوحيدة من المفتاح المزيف.new key but contains no user ID - skippedعند الاستيراد من keys.openpgp.org: صاحب المفتاح لم يؤكد بريده على السيرفر، فلا يعطيك السيرفر إلا المفتاح دون هوية، وGnuPG يرفضه. خذ المفتاح من مصدر آخر رسمي، أو اطلب من صاحبه أن يؤكد بريده.BAD signature: الملف تغير بعد توقيعه، أو أنك تتحقق من الملف الخطأ، فنزله من جديد من المصدر الرسمي ولا تستخدمه حتى ينجح التحقق.WARNING: This key is not certified with a trusted signature!معGood signature: التوقيع سليم، ولكنك لم تتحقق من المفتاح، فقارن البصمة المطبوعة في آخر سطر بالمصدر الرسمي، وإذا كان هذا المفتاح سوف يتكرر عندك فوقعه توقيعاً محلياً.
Inappropriate ioctl for device عند التوقيع أو فك التشفير: pinentry يحاول أن يسألك عن كلمة المرور ولا يعرف أي طرفية يستخدم، وهذا يحدث كثيراً داخل SSH أو tmux أو مع Git. وهذا ما ظهر لنا عندما وقعنا من Container دون طرفية:
$ gpg --clearsign t.txt
gpg: signing failed: Inappropriate ioctl for device
gpg: t.txt: clear-sign failed: Inappropriate ioctl for deviceوالحل كما في توثيق gpg-agent أن تضيف إلى ملف ~/.bashrc أو ما يقابله السطرين التاليين:
GPG_TTY=$(tty)
export GPG_TTYوبعد أن ضبطنا المتغير في طرفية حقيقية ظهر مربع pinentry في الطرفية بالنص «Please enter the passphrase to unlock the OpenPGP secret key» ونجح التوقيع. وإذا بقيت المشكلة بعد تغيير الإعداد فأعد تشغيل الوكيل بالأمر gpgconf --kill gpg-agent.
skipped: No public key عند التشفير مع أن المفتاح موجود: قد يكون المفتاح منتهياً أو ملغى، فالرسالة نفسها ظهرت لنا في الحالتين. واعرض المفتاح بالأمر gpg -k وانظر إلى [expired] أو [revoked]، ثم اطلب من صاحبه النسخة الجديدة. وقد اختبرنا المفتاح المنتهي في التجربة دون انتظار سنتين بالخيار --faked-system-time الذي يجعل GPG يعمل بتاريخ آخر:
$ gpg --faked-system-time 20290101T000000 --auto-key-locate local --armor --encrypt -r [email protected] report.txt
gpg: WARNING: running with faked system time: 2029-01-01 00:00:00
gpg: [email protected]: skipped: No public key
gpg: report.txt: encryption failed: No public keyودون الخيار --auto-key-locate local حاول GPG من نفسه أن يبحث عن مفتاح صالح عبر WKD على نطاق البريد، وهذا ما ظهر لنا لأن النطاق example.test غير موجود:
gpg: error retrieving '[email protected]' via WKD: Unknown host
gpg: [email protected]: skipped: Unknown hostإزالة التجربة
كل شيء كان داخل Container واحد بدأناه بالخيار --rm، فإيقافه يحذفه مع كل المفاتيح التجريبية، ثم نحذف ال Image التي بنيناها بالاسم:
docker stop lab-gpg-box
docker rmi lab-gpg-debian:13.7جدول الأوامر
| المهمة | الأمر |
|---|---|
| إنشاء مفتاح رئيسي | gpg --quick-gen-key "Name <mail>" ed25519 sign,cert 2y |
| إضافة مفتاح تشفير فرعي | gpg --quick-add-key FPR cv25519 encr 2y |
| عرض المفاتيح بالبصمات | gpg -K --keyid-format long --with-subkey-fingerprints |
| شهادة إلغاء بسبب | gpg --output revoke.asc --gen-revoke FPR |
| تصدير المفتاح العام | gpg --armor --export mail > key.asc |
| رفع المفتاح إلى keys.openpgp.org | gpg --keyserver hkps://keys.openpgp.org --send-keys FPR |
| استيراد مفتاح وعرض بصمته | gpg --import key.asc ثم gpg --fingerprint mail |
| عرض مفتاح دون استيراده | gpg --show-keys --fingerprint key.asc |
| توقيع محلي بعد التحقق | gpg --quick-lsign-key FPR |
| تشفير ملف | gpg --armor --encrypt -r mail file |
| تشفير وتوقيع | gpg --sign --encrypt --armor -r mail file |
| فك التشفير | gpg --decrypt file.asc |
| توقيع منفصل والتحقق منه | gpg --armor --detach-sign file ثم gpg --verify file.asc file |
| توقيع مقروء | gpg --clearsign file |
| توقيع Git | git config user.signingkey FPR وgit config commit.gpgsign true |
| التحقق في Git | git log --show-signature وgit verify-tag v1.0 |
| نسخة احتياطية | gpg --armor --export-secret-keys mail وgpg --export-ownertrust |
| تمديد الانتهاء | gpg --quick-set-expire FPR 2y ثم الأمر نفسه مع "*" |
تدريب عملي
- أنشئ مفتاحاً بالأوامر أعلاه في مجلد تجريبي بالمتغير
GNUPGHOME، واعرضه، وتأكد أن للمفتاح الرئيسي والفرعي تاريخ انتهاء، ثم انقل شهادة الإلغاء إلى مكان آخر. - نزل قائمة الهاش وتوقيعها لأي توزيعة تستخدمها، وابحث في موقعها الرسمي عن بصمة مفتاح التوقيع، وتحقق من القائمة ثم من ملف ISO نفسه.
- فعل توقيع ال Commits في مستودع تجريبي، وأنشئ Commit موقعاً وآخر غير موقع، وانظر إلى الفرق في
git log --format="%h %G? %s".
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- ثبت GnuPG من توزيعتك على Linux، أو من Homebrew أو GPG Suite على macOS، أو Gpg4win مع Kleopatra على Windows.
- أنشئ المفتاح بأمرين صريحين: مفتاح رئيسي ed25519 ومفتاح تشفير فرعي cv25519، ولكل منهما تاريخ انتهاء، وانظر إلى المخرج دائماً.
- انقل شهادة الإلغاء والنسخة الاحتياطية من المفتاح الخاص إلى مكان آمن بعيداً عن الجهاز اليوم وليس غداً.
- لا تشفر لمفتاح ولا تثق بتوقيع حتى تقارن البصمة الكاملة عبر قناة أخرى، ثم وقع المفتاح توقيعاً محلياً.
- عند التحقق من ملف منزل خذ المفتاح من الصفحة الرسمية لا من المرآة، وتحقق من التوقيع ثم من هاش الملف نفسه، وفي السكربتات استخدم حلقة مفاتيح فيها المفتاح المتوقع وحده.
- وقع Git Commits والوسوم بإعداد
user.signingkeyوcommit.gpgsign، فاسم الكاتب وحده يستطيع أي أحد أن يكتبه. - أغلب أخطاء GPG تقرأ مباشرة: مفتاح غير موجود، أو غير متحقق منه، أو منته، أو pinentry دون طرفية يحله
GPG_TTY.
دليلGPG وOpenPGP: شرح التشفير والتوقيع بالمفتاح العامكيف يعمل GPG بالمفتاح العام والخاص، ولماذا تقارن البصمة دائماً، وأين يحميك اليوم وأين لا يحميك.
دليلالتشفير للمطورين: ماذا تستخدم ولماذا لا تخترع خوارزميتكأي هاش تستخدم لكلمات المرور، ومتى تحتاج التشفير المتماثل أو غير المتماثل، وأين تحفظ المفاتيح بأمان في تطبيقك.
دليلإدارة النسخ وGit للمبتدئين: لماذا نحتاجها وكيف تعمللماذا تضيع الملفات بأسماء final_v2 ويمسح الزملاء عمل بعضهم، وكيف يحل Git ذلك على مشروع حقيقي من أول commit.
دليلالدخول دون كلمة مرور: شرح Passkeys وWebAuthnلماذا لا تحميك رموز SMS وTOTP من التصيد الحديث، وكيف تحل Passkeys المشكلة بمفتاح خاص لا يغادر جهازك.
دليلأمن سلسلة التوريد البرمجية Software Supply Chain للمبتدئينكل ما بين كود غيرك وسيرفرك قد يحمل كود المهاجم، وهنا تعرف التهديدات الحقيقية بحوادث موثقة والدفاع المناسب لكل حلقة.سجل التحديثات
- أكتوبر 2026: كتابة المقال، وتنفيذ كل الأوامر في Container من debian:13.7-slim مع GnuPG 2.4.7 وGit 2.47.3 وsqv 1.3.0، بمفاتيح تجريبية لشخصيات وهمية على النطاق example.test، والتحقق من ملفات Debian 13.7 الرسمية.