مقاله فنی

امضاهای PDF بلندمدت در دلفی: PAdES B-LT و B-LTA

برای اینکه یک فایل PDF امضاشده سال‌ها بعد، پس از انقضای گواهینامه امضا و تغییر مرجع صدور (CA)، همچنان تایید شود، کامپوننت PDFium می‌تواند امضاهای بلندمدت PAdES را روی ویندوز تولید کند: یک مهر زمانی RFC 3161 برای زمان معتبر، یک مخزن امنیت سند (Document Security Store) که مستندات اعتبارسنجی را تعبیه می‌کند، و یک مهر زمانی سند (DocTimeStamp) بایگانی روی کل فایل. این سه مورد سطوح پایه PAdES B-T، B-LT و B-LTA هستند، و کامپوننت PDFium با یک فراخوانی امضا به همه آنها دسترسی پیدا می‌کند. این یک قابلیت منحصر به ویندوز است که با ویژگی PadesCryptoAvailable کنترل می‌شود

این مقاله سومین بخش از این سری مقالات است. بخش اول، یعنی امضا کردن فایل‌های PDF با PAdES B-B با استفاده از نسخه PDFium VCL، امضای پایه را پوشش می‌دهد؛ بخش دوم، یعنی بررسی امضاهای دیجیتال PDF و سطوح PAdES، خواندن امضا و تعیین سطح به دست آمده را پوشش می‌دهد. در اینجا موضوع اصلی بایگانی است: امضاهایی که باید پس از انقضای گواهینامه دوام بیاورند و برای دوره‌های نگهداری که با سال سنجیده می‌شوند (نه با هفته)، معتبر باقی بمانند

چرا یک امضای PDF معتبر در طول زمان از کار می‌افتد؟

یک امضای پایه فقط به یک سؤال پاسخ می‌دهد: آیا این بایت‌ها پس از امضا تغییر کرده‌اند یا خیر. این امضا به خودی خود ثابت نمی‌کند که امضا چه زمانی رخ داده است، و این شکاف همان چیزی است که بعداً آن را بی‌اعتبار می‌کند. ساختار CMS حاوی ویژگی زمان امضا است، اما امضاکننده آن مقدار را از ساعت خود می‌نویسد، بنابراین یک ارزیاب دلیلی برای اعتماد به آن ندارد. هنگامی که گواهینامه امضا بعداً منقضی شود یا مرجع صدور آن را باطل کند، یک ارزیاب سخت‌گیر دیگر نمی‌تواند امضای ایجادشده در زمان اعتبار گواهینامه را از امضای جعلی ساخته‌شده پس از انقضای آن تشخیص دهد. امضا در روز ایجاد درست بوده است اما بدون هیچ تقصیری، غیرقابل تایید می‌شود

بایگانی بلندمدت این مشکل را در دو مرحله حل می‌کند. اول اینکه، یک شخص ثالث معتبر، یعنی یک مرجع مهر زمانی (Time Stamping Authority)، زمان را به صورت رمزنگاری تایید می‌کند تا دیگر به صداقت امضاکننده وابسته نباشد. دوم اینکه، هر گواهینامه، پاسخ ابطال و CRL مورد نیاز برای ساخت و بررسی زنجیره اعتماد در داخل خود فایل PDF تعبیه می‌شود، بنابراین اعتبارسنجی به سرورهایی که ممکن است تا زمان بررسی از دسترس خارج شده باشند، وابسته نیست. استاندارد PAdES که با نام ETSI EN 319 142-1 استانداردسازی شده است، این‌ها را به عنوان سطوح پایه لایه‌بندی می‌کند، و کامپوننت PDFium ساختارهای مورد نیاز هر سطح را می‌نویسد

امضای PDF با مهر زمانی بایگانی یا LTV چیست؟

استاندارد PAdES چهار سطح پایه را تعریف می‌کند که روی یکدیگر ساخته می‌شوند، و کامپوننت PDFium آنها را از طریق نوع شمارشی TPadesLevel (شامل plB_B، plB_T، plB_LT، plB_LTA) ارائه می‌دهد. سطح B-B همان امضای ساده است. سطح B-T یک مهر زمانی معتبر را روی مقدار امضا اضافه می‌کند. سطح B-LT (بلندمدت) مستندات اعتبارسنجی تعبیه‌شده را اضافه می‌کند، قابلیتی که بیشتر افراد از عبارت «LTV» منظور دارند. سطح B-LTA (بلندمدت با مهر زمانی بایگانی) همه چیز را در یک مهر زمانی دیگر که کل فایل را پوشش می‌دهد قرار می‌دهد، به طوری که خود مستندات تعبیه‌شده از لحظه بایگانی به طور اثبات‌پذیری دست‌نخورده باقی می‌مانند

برداشت عملی مانند یک پله است. سطح B-T ثابت می‌کند چه زمانی. سطح B-LT ثابت می‌کند با چه چیزی امضا همچنان می‌تواند بررسی شود. سطح B-LTA ثابت می‌کند که کل بسته از زمان مهر و موم شدن دست‌کاری نشده است، و این همان سطحی است که شما با افزودن یک DocTimeStamp جدید قبل از انقضای مهر زمانی قبلی، آن را تمدید می‌کنید تا بایگانی را به طور نامحدود تمدید نمایید. برای یک قرارداد یا سند انطباق با تعهد نگهداری طولانی، سطح B-LTA هدف نهایی است؛ و سطح B-LT حداقل سطح منطقی است

افزودن زمان معتبر: PAdES B-T با استاندارد RFC 3161

کامپوننت PDFium یک امضای B-B را با تنظیم دو فیلد در TPadesSignOptions به سطح B-T تبدیل می‌کند: ارتقای Level به plB_T و ارائه یک TsaUrl. هنگامی که هر دو وجود داشته باشند، خط لوله امضا بایت‌های امضای خام را با الگوریتم SHA-256 هش می‌کند، آن خلاصه پیام را به صورت messageImprint تحت استاندارد RFC 3161 بسته‌بندی می‌کند، درخواست را با متد POST از طریق WinHttp به مرجع مهر زمانی (TSA) ارسال می‌نماید، و توکن برگشت‌داده‌شده را به عنوان ویژگی امضانشده مهر زمانی (با شناسه OID 1.2.840.113549.1.9.16.2.14) در بخش unsignedAttrs [1] مربوط به SignerInfo بر اساس بند ۶.۳ استاندارد EN 319 142-1 تعبیه می‌کند. این مهر زمانی به طور خاص مقدار امضا را پوشش می‌دهد، که همان چیزی است که زمان معتبر را به آن امضای دقیق متصل می‌کند

uses
  PDFium, FPdfPades;

procedure SignWithTimestamp;
var
  Pdf: TPdf;
  Options: TPadesSignOptions;
begin
  Pdf := TPdf.Create(nil);
  try
    if not Pdf.PadesCryptoAvailable then
      raise Exception.Create('PAdES signing backend is Windows-only');
    Pdf.FileName := 'contract.pdf';
    Pdf.Active := True;

    Options := TPadesSignOptions.Default;
    Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
    Options.Level  := plB_T;
    Options.TsaUrl := 'http://timestamp.example-tsa.com/tsr';
    Options.Reason := 'Contract execution';
    // Nonce left at 0: the component derives a unique anti-replay value.

    Pdf.SignPades('contract-bt.pdf', Options);
  finally
    Pdf.Free;
  end;
end;

مقدار CertificateThumbprint همان هش SHA-1 به صورت هگز از گواهینامه‌ای در مخزن «MY» کاربر فعلی (Current User) است که می‌توانید از کلید خصوصی آن استفاده کنید. فیلد Nonce مقدار جلوگیری از تکرار درخواست (anti-replay) تحت استاندارد RFC 3161 است؛ اگر آن را صفر بگذارید، کامپوننت با یک ترکیب SHA-256 از یک شمارنده، ساعت، تعداد تیک‌ها و شناسه پروسه، یک مقدار منحصربه‌فرد برای هر درخواست استخراج می‌کند، بنابراین دو درخواست صادرشده در یک میلی‌ثانیه با هم برخورد نمی‌کنند. تنها زمانی مقدار خود را ارسال کنید که یک مولد عدد تصادفی (RNG) رمزنگاری‌شده داشته باشید که به آن اعتماد بیشتری دارید. یک نکته واقع‌بینانه: سطح B-T به یک TSA در دسترس نیاز دارد، بنابراین ثبت امضا اکنون یک فراخوانی شبکه انجام می‌دهد و زمان پاسخ و در دسترس بودن TSA روی آن تاثیرگذار خواهد بود

تعبیه مستندات اعتبارسنجی: B-LT و B-LTA در یک فراخوانی

گام برداشتن به سمت اعتبارسنجی بلندمدت یک تغییر واحد است: تنظیم Level روی plB_LTA و نگه داشتن TsaUrl. سپس کامپوننت PDFium کل این مراحل را در یک فراخوانی SignPades اجرا می‌کند. امضای B-B را ثبت می‌کند، مهر زمانی برای B-T می‌زند، Document Security Store را برای B-LT تزریق می‌کند و مهر زمانی بایگانی را برای B-LTA اضافه می‌کند، که هر کدام به صورت به‌روزرسانی افزایشی (incremental update) خود انجام می‌شوند تا بایت‌های قبلی بایت‌به‌بایت دست‌نخورده باقی بمانند

procedure SignForArchive;
var
  Pdf: TPdf;
  Options: TPadesSignOptions;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'contract.pdf';
    Pdf.Active := True;

    Options := TPadesSignOptions.Default;
    Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
    Options.Level    := plB_LTA;   // drives B-B -> B-T -> B-LT -> B-LTA
    Options.TsaUrl   := 'http://timestamp.example-tsa.com/tsr';
    Options.Location := 'Head Office';

    // One call writes the timestamp, the DSS and the archive DocTimeStamp.
    Pdf.SignPades('contract-lta.pdf', Options);
  finally
    Pdf.Free;
  end;
end;

برای مرحله B-LT، کامپوننت PDFium زنجیره گواهینامه را با متد CertGetCertificateChain می‌سازد و یک دیکشنری /DSS حاوی گواهینامه امضاکننده به همراه هر مرجع صدور میانی (intermediate CA) در یک آرایه /Certs (همراه با آرایه‌های موازی /OCSPs و /CRLs) می‌نویسد، در کنار نشانگر /Extensions /ESIC در سطح ۱، دقیقاً همان‌طور که بند ۵.۴.۲ استاندارد EN 319 142-1 تعیین کرده است. گواهینامه ریشه خودامضاشده (self-signed root) عمداً حذف می‌شود، زیرا استاندارد RFC 5652 §10.2.3 این اجازه را می‌دهد و ریشه از قبل یک نقطه اعتماد (trust anchor) است که ارزیاب در اختیار دارد. نتیجه امضایی است که خواننده می‌تواند بدون هیچ چیز دیگری و فقط با در دست داشتن فایل آن را تایید کند.

برای سطح B-LTA، کامپوننت یک مهر زمانی سند (Document Time-stamp) اضافه می‌کند: یک دیکشنری امضا با ویژگی /SubFilter /ETSI.RFC3161 که /ByteRange آن کل فایل را در بر می‌گیرد، و ورودی /Contents آن حاوی یک توکن RFC 3161 روی آن محدوده است، و همچنین نشانگر ESIC را به سطح ۲ ارتقا می‌دهد. این مرحله بایگانی بر اساس بند ۵.۴.۳ و استاندارد TS 119 142-3 است. از آنجا که DocTimeStamp علاوه بر امضا، بخش DSS را نیز پوشش می‌دهد، ثابت می‌کند که مستندات اعتبارسنجی تعبیه‌شده در زمان بایگانی وجود داشته و دست‌نخورده بوده‌اند، که این دقیقاً همان چیزی است که یک سیاست نگهداری طولانی باید بتواند نشان دهد

ارتقای امضایی که از قبل وجود دارد

گاهی اوقات امضا از قبل روی سند وجود دارد و شما فقط نیاز به افزودن یا به‌روزرسانی مخزن اعتبارسنجی دارید، به عنوان مثال برای ارتقای یک امضای B-B شخص ثالث به سطح B-LT برای بایگانی خود. کامپوننت PDFium تزریق‌کننده DSS را مستقیماً از طریق متد SaveAsPadesDss ارائه می‌دهد، که ساختارهای /DSS و /Extensions را به عنوان یک به‌روزرسانی افزایشی و بدون دست زدن به بایت‌های امضای موجود اضافه می‌کند

procedure AddValidationStore;
var
  Pdf: TPdf;
  DssOpts: TPadesDssOptions;
  Cert: TPadesDssMaterial;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'already-signed.pdf';
    Pdf.Active := True;

    DssOpts := TPadesDssOptions.Default;
    DssOpts.EsicExtensionLevel := 1;         // 1 for B-LT, 2 for B-LTA
    Cert.DerBytes := LoadSignerCertDer;       // your DER-encoded certificate
    SetLength(DssOpts.Certs, 1);
    DssOpts.Certs[0] := Cert;

    Pdf.SaveAsPadesDss('already-signed-lt.pdf', DssOpts);
  finally
    Pdf.Free;
  end;
end;

شما گواهینامه‌های رمزگذاری‌شده با فرمت DER، و به صورت اختیاری پاسخ‌های OCSP و CRLها را که ارزیاب نیاز دارد ارائه می‌دهید. مقدار EsicExtensionLevel را برای مخزن B-LT روی ۱ یا در صورتی که DocTimeStamp بعد از آن بیاید روی ۲ تنظیم کنید. مقدار IncludeVri را روی پیش‌فرض False رها کنید: بند ۵.۴.۲.۳ استاندارد EN 319 142-1 دیکشنری /VRI مخصوص هر امضا را اختیاری در نظر می‌گیرد و توصیه می‌کند که از آن استفاده نشود مگر اینکه برنامه خواننده خاصی که هدف شماست آن را درخواست کند

هزینه‌ها و مرزهایی که ارزش برنامه‌ریزی دارند

سه محدودیت واقعی شکل استفاده از این سطوح را تعیین می‌کنند. اول اینکه، پس‌زمینه رمزنگاری منحصر به ویندوز است: ثبت امضا و ثبت مهر زمانی از طریق مخازن CNG پلتفرم و WinHttp انجام می‌شود، بنابراین ویژگی PadesCryptoAvailable در سایر سیستم‌عامل‌ها مقدار False را برمی‌گرداند و متد SignPades خطا ایجاد می‌کند. بررسی بخش خواندن که در مقاله همراه پوشش داده شده است به صورت cross-platform باقی می‌ماند؛ و فقط نوشتن امضاها به ویندوز محدود است. دوم اینکه، سطوح B-T و B-LTA به مرجع مهر زمانی (TSA) وابسته هستند، که به معنای یک رفت و برگشت شبکه در زمان امضا و یک سرویس خارجی است که در دسترس بودن و محدودیت‌های سرعت آن به بخشی از مسیر امضای شما تبدیل می‌شود

سوم اینکه، هر سطح هزینه‌ای برای ذخیره‌سازی دارد. هر مرحله به جای بازنویسی فایل، یک به‌روزرسانی افزایشی اضافه می‌کند، بخش DSS یک زنجیره گواهینامه کامل را تعبیه می‌کند، و DocTimeStamp بایگانی فضا را برای توکن خود رزرو می‌نماید، بنابراین یک فایل B-LTA به طور محسوسی بزرگ‌تر از نسخه اصلی B-B است. این یک معامله آگاهانه است: شما اکنون بایت‌ها را مصرف می‌کنید تا بعداً قابلیت تایید را به دست آورید. برای بیشتر بایگانی‌های قراردادها و اسناد انطباق، این یک معامله درست است، اما ارزش دارد که آن را روی اسناد خود اندازه‌گیری کنید به جای اینکه فرض‌هایی داشته باشید. وقتی می‌خواهید تأیید کنید که یک فایل نهایی واقعاً به سطح مورد نظر شما رسیده است، آن را با روش‌های ذکرشده در بخش بررسی امضاهای دیجیتال PDF و سطوح PAdES تایید کنید، و اگر در حال مقاوم‌سازی گسترده‌تر خط لوله اسناد هستید، یادداشت‌های مربوط به ممیزی ریسک‌های امنیتی PDF بررسی‌های پیرامون آن را پوشش می‌دهند

قابلیت‌های امضای PAdES، مخزن DSS و مهر زمانی بایگانی نشان داده شده در اینجا بخشی از PDFium Component برای دلفی و سی‌پلاس‌پلاس‌بیلدر هستند که صفحه محصول آنها حاوی مستندات کامل امضا و پیش‌نیازهای پلتفرم است