مقاله فنی

رمزنگاری AES-GCM در PDF 2.0 با Delphi: ISO/TS 32003

PDFiumPas رمزنگاری ISO/TS 32003 را از طریق SaveAsEncrypted می‌نویسد: Revision را روی erR7 تنظیم کنید و هر رشته و جریان با AES-256 در حالت GCM محافظت می‌شود، همان رمز احرازشده‌ای که PDF 2.0 در سال 2023 به‌دست آورد. EnableIntegrityProtection را هم تنظیم کنید و سند یک توکن مستقل PDF MAC هم حمل می‌کند، که ValidatePdfMac در سمت خواندن آن را بررسی می‌کند

این‌ها دو محافظت متفاوت هستند که مردم به‌طور معمول با هم اشتباه می‌گیرند. GCM هر مقدار رمزنگاری‌شده را احراز می‌کند. MAC کل سند را به‌عنوان یک واحد احراز می‌کند. شما هر دو را می‌خواهید، به دلایل متفاوت

GCM چه چیزی اضافه می‌کند که CBC هرگز فراهم نکرده؟

احراز متن رمزشده. AES-256 در حالت CBC، طرح AESV3 در ISO 32000-2، محتوا را محرمانه نگه می‌دارد و هیچ‌چیز درباره اینکه آیا بدون تغییر رسیده نمی‌گوید. CBC به روش‌های خاص و به‌خوبی مطالعه‌شده‌ای چکش‌خوار است: مهاجمی که می‌تواند بیت‌ها را در متن رمزشده بچرخاند تغییرات قابل‌پیش‌بینی‌ای در متن ساده بلوک بعدی تولید می‌کند، و هیچ‌چیز در قالب متوجه نمی‌شود

GCM آن را می‌بندد. هر مقدار رمزنگاری‌شده یک تگ احراز 16 بایتی حمل می‌کند، که به‌طور کامل همان‌طور که ISO/TS 32003 لازم دارد سریالی شده، و رمزگشایی به‌جای بازگرداندن متن ساده تغییریافته، وقتی تگ مطابقت ندارد شکست می‌خورد. از نظر PDF، یک رشته یا جریان دستکاری‌شده در یک سند AESV4 یک خطای سخت در نقطه استفاده است، نه یک مقدار عجیب که به برنامه شما سرایت می‌کند. دیکشنری Encrypt این را با /CFM /AESV4 و V 6 / R 7 علامت می‌زند، به‌همراه یک مدخل extensions که /ExtensionLevel 32003 و /ExtensionRevision (:2023) را اعلام می‌کند

سه نسخه، سه اکوسیستم

TPdfEncryptionRevision مقادیر erR5، erR6 و erR7 را ارائه می‌دهد، و انتخاب بیشتر یک تصمیم سازگاری است تا یک تصمیم رمزنگاری. R5 همان طرح اصلی AES-256 است که به‌عنوان یک افزونه PDF 1.7 منتشر شد، با یک هش رمز عبور SHA-256 واحد، و اساساً در هرچیزی از پانزده سال گذشته باز می‌شود. R6 اشتقاق کلید سخت‌شده استانداردسازی‌شده در ISO 32000-2 است، با استفاده از ساختار تکرارشونده SHA-256/384/512 الگوریتم 2.B، و همان چیزی است که یک جریان کاری فعلی PDF 2.0 یا PDF/A-4 انتظار دارد. R7 همان ISO/TS 32003 است، با استفاده از همان اشتقاق 2.B با AES-GCM به‌عنوان رمز

پشتیبانی نمایشگرها دقیقاً به همان ترتیب پیش می‌رود، و پشتیبانی R7 هنوز بیرون از نمایشگرهای اصلی فعلی کم‌رمق است. این همان مصالحه‌ای است که بر هر ویژگی PDF 2.0 حاکم است: جدیدترین گزینه بهترین مهندسی و باریک‌ترین مخاطب را دارد. بر اساس اینکه چه‌کسی باید فایل را باز کند تصمیم بگیرید، و اگر آن پاسخ «یک سیستم بایگانی که هیچ‌کس از 2019 آن را به‌روز نکرده» باشد، پاسخ R5 است، صرف‌نظر از اینکه سیاست امنیتی چه چیزی ترجیح می‌دهد

uses
  PDFium, FPdfEncrypt;

var
  Pdf: TPdf;
  Opts: TPdfEncryptOptions;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'quarterly-report.pdf';
    Pdf.LoadDocument;

    Opts := TPdfEncryptOptions.Default;
    Opts.UserPassword := 'open-secret';
    Opts.OwnerPassword := 'admin-secret';
    Opts.EncryptMetadata := True;
    Opts.Revision := erR7;                    // ISO/TS 32003 AESV4-GCM
    Opts.EnableIntegrityProtection := True;   // توکن PDF MAC مستقل

    if not Pdf.SaveAsEncrypted('quarterly-report.enc.pdf', Opts) then
      raise Exception.Create('Encrypted save failed');
  finally
    Pdf.Free;
  end;
end;

چرا یک MAC سند روی یک رمز احرازشده؟

چون تگ‌های GCM از مقادیر محافظت می‌کنند، نه از چیدمان مقادیر. هر رشته و جریان در یک سند AESV4 به‌طور جداگانه احراز می‌شود، با این حال جدول ارجاع متقابل، شماره‌گذاری اشیاء و trailer ساختار هستند، نه محتوای رمزنگاری‌شده. یک مهاجم نمی‌تواند یک جریان را جعل کند، اما هیچ‌چیز در خود رمز به‌تنهایی مانع آن نمی‌شود که ترتیب اینکه سند به کدام اشیاء اشاره می‌کند را دوباره‌چینی کند، یا اشیائی از یک نسخه قدیمی‌تر همان فایل را پیوند بزند

توکن مستقل PDF MAC آن لایه را حل می‌کند. PDFiumPas آن را از کلید رمزنگاری فایل با یک /KDFSalt اختصاصی 32 بایتی ثبت‌شده در دیکشنری Encrypt مشتق می‌کند، پس در اختیار داشتن رمز عبور همان چیزی است که به یک خواننده اجازه می‌دهد توکن را تأیید کند. نتیجه یک پاسخ واحد به یک سؤال واحد است: آیا این سند، به‌عنوان یک کل، همان سندی است که نوشته شده

var
  Pdf: TPdf;
  Mac: TPdfMacValidationResult;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.Password := 'open-secret';
    Pdf.FileName := 'quarterly-report.enc.pdf';
    Pdf.LoadDocument;

    Mac := Pdf.ValidatePdfMac('open-secret');
    case Mac.Status of
      pmvsValid:       ProcessDocument(Pdf);
      pmvsNotPresent:  ProcessWithWarning(Pdf);       // هیچ توکنی در این فایل نیست
      pmvsInvalid:     Quarantine(Mac.MessageText);   // دستکاری‌شده یا کوتاه‌شده
      pmvsUnsupported: RouteForManualReview(Mac.MessageText);
    end;
  finally
    Pdf.Free;
  end;
end;

چهار مقدار وضعیت به چهار پاسخ متفاوت نیاز دارند، و فروکاستن آن‌ها به یک بولی، تمایزی را که اهمیت دارد از بین می‌برد. pmvsNotPresent یعنی فایل صرفاً توکنی ندارد، که تقریباً هر PDF رمزنگاری‌شده نوشته‌شده پیش از 2024 را توصیف می‌کند و مدرکی بر هیچ‌چیز نیست. pmvsInvalid یعنی یک توکن حاضر است و تأیید نمی‌شود، که یک یافته واقعی است و باید پردازش را متوقف کند. pmvsUnsupported یعنی توکن به شکلی وجود دارد که این نسخه ساخته‌شده پیاده‌سازی نکرده، که یک شکاف سازگاری است، نه یک حمله. رفتار با «حاضر نیست» به‌عنوان «نامعتبر» کل کاتالوگ قدیمی شما را در همان روز اول قرنطینه می‌کند

رمزنگاری هنوز چه کاری انجام نمی‌دهد

پرچم‌های دسترسی همان چیزی باقی می‌مانند که همیشه بودند: یک درخواست از نرم‌افزار سازگار، نه یک کنترل. بیت‌های /P از Table 22 در ISO 32000-1 که چاپ یا استخراج را ممنوع می‌کنند، توسط نمایشگرهای خوش‌رفتار رعایت و توسط هرچیز دیگر نادیده گرفته می‌شوند، و هرکسی که رمز عبور کاربر را در اختیار دارد از پیش محتوای رمزگشایی‌شده را در اختیار دارد. رمزنگاری همان مرز است؛ مجوزها نیت را درون آن توصیف می‌کنند

دو جزئیات عملیاتی ارزش برنامه‌ریزی دارند. اول، رمزنگاری و تغییر بعدی با هم تعامل دارند: ضمیمه‌کردن یک به‌روزرسانی افزایشی به یک سند رمزنگاری‌شده قواعد خودش را دارد، که در به‌روزرسانی‌های افزایشی روی PDFهای رمزنگاری‌شده پوشش داده شده، و یک توکن MAC یک اظهار در سطح سند است که یک ضمیمه بی‌دقت آن را باطل می‌کند. دوم، ساختار GCM از یک شمارنده IV قطعی استفاده می‌کند، و PDFiumPas به‌جای استفاده مجدد از یک مقدار شمارنده در صورت اتمام آن فضا، خطا صادر می‌کند، چون استفاده مجدد از nonce در GCM به شکلی فاجعه‌بار است که یک چرخش بی‌صدا آن را پنهان می‌کرد

انتخاب بین سه نسخه در عمل

بنویسید چه‌کسی فایل را باز می‌کند، سپس انتخاب کنید. برای توزیع داخلی که هر خواننده یک نمایشگر فعلی تحت کنترل شماست، R7 همراه با محافظت یکپارچگی قوی‌ترین گزینه موجود است و هیچ دلیلی برای استفاده‌نکردن از آن نیست. برای اسنادی که سازمان را ترک می‌کنند، R6 پیش‌فرض قابل‌دفاع است: آن در ISO 32000-2 استانداردسازی شده نه در یک مشخصه فنی روی آن، و پشتیبانی گسترده است. برای بایگانی‌ها و مصرف‌کنندگان قدیمی، R5 تنها انتخابی است که به‌طور قابل‌اتکا باز می‌شود، و باید دلیل آن را در همان جایی که باقی سیاست نگه‌داری خود را ثبت می‌کنید بنویسید

هرکدام را که انتخاب کنید، خروجی را اعتبارسنجی کنید به‌جای اینکه به موفقیت فراخوانی اعتماد کنید. فایل رمزنگاری‌شده را دوباره باز کنید، ValidatePdfMac را بررسی کنید، و با استفاده از بررسی‌های انطباق نسخه در انطباق دقیق نسخه PDF تأیید کنید که نسخه اعلام‌شده همان چیزی است که انتظار دارید. یک چک‌لیست دریافت گسترده‌تر برای اسناد نامعتبر در بازبینی ریسک‌های امنیتی PDF موجود است

PDFiumPas یک کامپوننت Delphi و Lazarus حول موتور PDFium است که پشته رمزنگاری PDF 2.0 را به‌طور بومی در Pascal پیاده‌سازی می‌کند، پس AES-256، GCM و توکن MAC به هیچ DLL رمزنگاری خارجی نیاز ندارند. API رمزنگاری در صفحه کامپوننت Delphi PDFium مستند شده است