مقال تقني

تشفير PDF باستخدام AES-256 في Delphi: إعداد HotPDF والمزالق

نص تذكرة الدعم كان واضحا: "تفتح كشوف الحسابات جيدا على أجهزة سطح المكتب لدينا، لكن نظام إدارة السجلات لدى العميل يعلّم كل ملف على أنه غير قابل للقراءة". كانت ملفات PDF مشفرة باستخدام AES-256، تماما كما يطلب العقد. كان السبب الجذري في قيمة boolean واحدة: كُتبت المستندات بمراجعة التشفير 6، وهي صيغة PDF 2.0 من ISO 32000-2، بينما لم تكن سلسلة أدوات الأرشفة لدى العميل تفهم إلا المراجعة 5. الخوارزمية نفسها، وطول المفتاح نفسه، وكلمات المرور نفسها، لكن مصافحة اشتقاق مفتاح مختلفة، وفشل قاطع لم يظهر قط على أي جهاز تطوير يشغل إصدارا حديثا من Acrobat

التشفير من ميزات PDF القليلة التي قد ينتج فيها الإعداد الخاطئ بلا أي عرض مرئي محليا، ثم فشل كامل بعيدا عند العميل. يتيح HotPDF، وهو مكوّن PDF أصلي VCL لـ Delphi وC++Builder، نموذج الحماية الكامل في ISO 32000 عبر مجموعة صغيرة من الخصائص؛ وتربط هذه المقالة كل خاصية بالقرار الحقيقي الذي تتحكم فيه

ما الذي تعد به كلمتا المرور فعليا

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

الأذونات نفسها، مثل الطباعة واستخراج المحتوى وملء النماذج، وعد أضعف. إنها أعلام يقرؤها العارض ويوافق على احترامها كما في ISO 32000-2 §7.6.4. يحمي التشفير البايتات؛ أما أعلام الأذونات فهي لا تفعل سوى إرشاد البرامج المطابقة. المستخدم الذي يفتح المستند شرعيا بكلمة مرور المستخدم يملك المحتوى مفكوك التشفير في الذاكرة، ولذلك فإن "منع النسخ" و"منع الطباعة" إشارات سياسة للعارضات حسنة السلوك، لا ضمانات تشفيرية. ابن نموذج التهديد حول هذا الفصل: السرية تأتي من كلمة مرور المستخدم، بينما تشكّل أعلام الأذونات السلوك في العارضات الشائعة ولا أكثر

ترتيب الإعداد: كل شيء قبل BeginDoc

ينشئ HotPDF قاموس التشفير ومفتاح الملف عند تشغيل BeginDoc. لذلك يجب تعيين كل خاصية حماية أولا، وخصوصا CryptKeyLength التي تختار المخطط عبر قيم THPDFKeyType: k40 وk128 وaes128 وaes256. تعيينها بعد BeginDoc لا يطلق استثناء؛ المستند يحتفظ ببساطة بالمعاملات التي بدأ بها، وهذا بالضبط نوع الانحراف الصامت الذي يظهر بعد أشهر كمسألة امتثال

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'statement.pdf';
    Pdf.ActivateProtection := True;
    Pdf.CryptKeyLength := aes256;        // must be set before BeginDoc
    Pdf.UserPassword := 'open-secret';
    Pdf.OwnerPassword := 'admin-secret';
    Pdf.UseAES256R6 := False;            // R=5: widest viewer support
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 720, 0, 'Account statement, June 2026');
    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

كلمات المرور بتشفير UTF-8 وبحد أقصى 127 بايت، بما يطابق حد ISO 32000-2 لمخططات AES-256. إذا كانت سياسة كلمات المرور لديك تولد أسرارا أطول، فاقطعها عمدا من جهتك بدلا من ترك المكتبة وقارئ مستقبلي يختلفان حول موضع القطع

المراجعة 5 أم المراجعة 6: boolean واحد ونظامان بيئيان

تختار UseAES256R6 بين مصافحتي AES-256. عندما تكون False يكتب HotPDF المراجعة 5، وهي مخطط AES-256 الذي أُدخل كامتداد إلى PDF 1.7 وتدعمه إصدارات عارضات تمتد إلى نحو خمسة عشر عاما. وعندما تكون True يكتب المراجعة 6، وهي خوارزمية اشتقاق المفاتيح المشددة التي وُحّدت في ISO 32000-2 من أجل PDF 2.0، وهي الصيغة التي تغلق الضعف المعروف في خطوة التحقق من كلمة المرور في المراجعة 5

المفاضلة الهندسية هنا هي التوافق مقابل التوحيد. تتطلب المراجعة 6 عارضات مبنية لـ PDF 1.7 Extension Level 3 أو PDF 2.0؛ أما أنظمة الأرشفة الأقدم، والعارضات المضمنة، وأدوات الأعمال غير المصانة فقد تفشل في فتح الملف تماما، كما حدث في التذكرة في بداية المقالة. ما لم تسم سياسة أمنية صراحة ISO 32000-2 revision 6، اشحن المراجعة 5 وسجل القرار، فهي الافتراضي الأكثر أمانا، ويمكنك مراجعته عندما يحدّث أبطأ مستهلك لديك أدواته

ينطبق المنطق نفسه على مستوى أدنى. ما زال THPDFKeyType يوفر k40 وk128 وaes128 للتوافق مع سلاسل أدوات أقدم، لكن الثلاثة جميعا تخص أعمال صيانة أنظمة موروثة، لا تصميمات جديدة: RC4 بقدرة 40 بت قابل للكسر على عتاد عادي، ومخططات 128 بت تسبق مراجع AES-256 التي تتوقعها مراجعات الأمن الحالية. لأي مستند يُنتج في 2026، مساحة القرار الواقعية هي AES-256 revision 5 مقابل revision 6؛ أما أنواع المفاتيح الأقدم فموجودة كي تستطيع إعادة إنتاج أرشيفات تاريخية، لا كي تكتب بها مستندات جديدة

أعلام الأذونات من دون كلمة مرور فتح

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

Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.UserPassword := '';                      // anyone can open the file
Pdf.OwnerPassword := 'rotate-me-quarterly';  // guards the permission set
Pdf.ProtectOptions := [prPrint, prPrint12bit, prExtractContent];
Pdf.BeginDoc;
// ... page content ...
Pdf.EndDoc;

تغطي مجموعة THPDFProtectOptions بتات الأذونات في ISO: prPrint وprPrint12bit للطباعة عالية الدقة، وprInformationCopy للنسخ والاستخراج العامين، وprExtractContent لاستخراج تقنيات المساعدة، وprModifyStructure وprEditAnnotations وprFillAnnotations وprAssemble. يستحق اثنان منها نصيحة خاصة. أبق prExtractContent مفعلا في كل ملف تعريف تقريبا، فهو البت الذي يسمح لقارئات الشاشة وتقنيات المساعدة الأخرى بالوصول إلى المحتوى، وسحبه يحول قرار حقوق إلى عيب إتاحة. ولاحظ أن prPrint من دون prPrint12bit ينتج طباعة منخفضة الجودة في بعض العارضات، وهو ما يبلّغ عنه المستخدمون كخلل عرض لا كإذن

التحقق سريع ويستحق التشغيل الآلي ضمن فحوص الإصدار: افتح عينة من مخرجات كل ملف تعريف في Acrobat واقرأ تبويب Security في Document Properties، حيث يسمي الخوارزمية ("AES 256-bit") ويفصل العمليات المسموح بها واحدة تلو الأخرى. ثم أعد الفتح في أقدم عارض يستخدمه عملاؤك فعليا. الدقائق الخمس التي يكلفها الفحص الثاني هي بالضبط الفجوة التي سمحت لتذكرة المراجعة 6 في بداية هذه المقالة بالوصول إلى الإنتاج

إزالة الحماية من الملفات الموجودة

فك التشفير هو نموذج الخصائص نفسه بالعكس: حمّل المستند بالاعتماد الخاص به، أوقف الحماية، ثم احفظ النتيجة

var
  Pdf: THotPDF;
  PageCount: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    PageCount := Pdf.LoadFromFile('encrypted.pdf', 'open-secret');
    if PageCount > 0 then
    begin
      Pdf.ActivateProtection := False;   // drop encryption on save
      Pdf.SaveLoadedDocument('plain.pdf');
    end;
  finally
    Pdf.Free;
  end;
end;

هذا المسار يفسر المستند كاملا، وهو مناسب للملفات العادية. للمدخلات التي تبلغ مئات الميغابايت هناك مسار أرخص: DecryptFile يفك التشفير أثناء نسخ على مستوى الملف، آخذا مسار إعادة كتابة مباشر لـ AES-256 يتجنب بناء شجرة الكائنات متى سمح الإدخال بذلك. هذا ينتمي إلى Direct File API الموضحة في المقالة المرافقة عن معالجة ملفات PDF الكبيرة من Delphi

قيود تتفاعل مع التشفير

تتعارض ملفات التعريف الأرشيفية مباشرة: يحظر ISO 19005 التشفير في ملفات PDF/A، ولذلك فإن مسار عمل يشفّر مستندا ويدّعي في الوقت نفسه التوافق مع PDF/A غير صالح من الأساس. عندما يوجد المتطلبان معا، سلّم أثرين منفصلين: نسخة توزيع مشفرة ونسخة أرشيف غير مشفرة، بدلا من محاولة تلبيتهما في ملف واحد

ولا يوجد مسار استرداد أيضا. لا يملك تشفير PDF آلية escrow: فقدان كلمة مرور المستخدم في ملف R5 أو R6 يعني الهجوم بالقوة الغاشمة أو لا شيء. تعامل مع أسرار المالك والمستخدم كاعتمادات إنتاج: مولدة، محفوظة في خزنة، ومدارة بالتدوير، ولا تجعلها ثوابت في وحدة، حيث تنتهي في نظام التحكم بالإصدارات وفي نسخة عمل كل مطور

أسئلة شائعة: حماية ملفات PDF من Delphi

هل يوقف تعطيل prInformationCopy نسخ النص؟

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

هل يجب على مشروع جديد تفعيل UseAES256R6؟

فقط عندما يُتحقق من أن كل مستهلك يستطيع التعامل مع تشفير PDF 2.0. توفر المراجعة 5 تشفير محتوى AES-256 نفسه مع تغطية عارضات أوسع بكثير، ولهذا هي الافتراضي

هل أستطيع تغيير الأذونات في PDF لم أنشئه؟

نعم، حمّله بكلمة المرور عبر LoadFromFile، وعدّل ProtectOptions أو كلمات المرور، واكتب النتيجة باستخدام SaveLoadedDocument، تماما كما في مثال فك التشفير أعلاه

خصائص الحماية المعروضة هنا جزء من HotPDF Component القياسي لـ Delphi وC++Builder؛ وتعرض صفحة المنتج مرجع التشفير الكامل، بما في ذلك تعداد الأذونات كاملا