Artikel Teknis

Bukti LTV PAdES dan Seed Value di HotPDF

PDF yang baru saja Anda tanda tangani adalah tanda tangan B-B dan tidak lebih. Ia membuktikan siapa yang menandatangani dan bahwa byte-nya tidak berpindah, tetapi tidak membawa bukti bahwa sertifikat penandatangan valid pada saat penandatanganan, sehingga validator bertahun-tahun kemudian harus mencari data revokasi yang mungkin sudah tidak ada. Menutup celah itu berarti menulis respons OCSP dan CRL ke Document Security Store level dokumen, dan di HotPDF itu satu panggilan: PopulatePAdESLTVEvidence menelusuri setiap tanda tangan yang dimuat, menurunkan permintaan revokasi dari set sertifikat, mengeksekusinya melalui transport yang Anda sediakan, dan menulis materi yang diperoleh beserta rantai CMS ke DSS. Ia mengembalikan jumlah tanda tangan yang buktinya berhasil mendarat, atau minus satu ketika dokumen sama sekali tidak punya signature field

Keputusan desain yang layak dipahami sebelum Anda memakainya adalah pustaka tidak pernah membuka socket. Setiap byte yang datang dari jaringan datang melalui callback yang Anda tulis. Itu bukan kehati-hatian untuk kehati-hatian semata; itu satu-satunya cara fitur ini dapat bekerja di dalam lingkungan yang benar-benar menuntut validasi jangka panjang

Mengapa pustaka menolak melakukan HTTP sendiri?

Karena tempat-tempat yang mensyaratkan tanda tangan B-LT adalah tempat-tempat di mana pustaka tidak bisa dipercaya dengan jaringan. Layanan penandatanganan berjalan di belakang proxy autentikasi dengan corporate root. Tingkat penandatanganan yang air-gapped tidak punya rute ke responder dan harus diberi makan bukti yang di-cache. Rezim audit mensyaratkan setiap permintaan keluar dicatat oleh aplikasi, bukan terkubur dalam sebuah dependensi. Dan test suite membutuhkan respons deterministik, yang mustahil jika pustaka menelepon keluar dengan kemauannya sendiri

Transport-nya adalah function reference polos dengan bentuk tetap, sehingga kebijakannya tetap milik Anda. HotPDF menyerahkan kepada Anda record permintaan yang menjelaskan persis apa yang harus diambil, termasuk content type dan batas ukuran respons, dan Anda mengembalikan byte plus status

Alur PopulatePAdESLTVEvidence HotPDF: transport FetchEvidence yang disediakan caller, field record permintaan, dan status hasil per tanda tangan
Setiap byte jaringan melewati callback FetchEvidence Anda, dan setiap tanda tangan mendapat statusnya sendiri sehingga satu timeout tidak pernah membatalkan lintasan
function FetchEvidence(const Request: THPDFSignatureEvidenceRequest;
  Attempt: Integer; CancellationToken: THPDFCancellationToken;
  out Response: TBytes; out RetryAfterMS: Cardinal;
  out ErrorMessage: UnicodeString): THPDFSignatureEvidenceTransportStatus;
begin
  RetryAfterMS := 0;
  try
    // Request.Kind menyatakan apakah ini OCSP POST atau CRL GET;
    // Request.ContentType dan Request.Body sudah disiapkan,
    // dan Request.MaxResponseBytes adalah batas yang harus Anda hormati
    Response := HttpExchange(Request.URI, Request.ContentType,
      Request.Body, Request.MaxResponseBytes);
    Result := setsSucceeded;
  except
    on E: Exception do
    begin
      ErrorMessage := E.Message;
      // setsRetry membiarkan kebijakan retry mundur; gunakan
      // setsPermanentFailure untuk 404 atau URL yang buruk
      Result := setsRetry;
    end;
  end;
end;

// Upgrade satu panggilan dari B-B ke B-LT untuk setiap tanda tangan
// di berkas yang dimuat
var
  Pdf: THotPDF;
  Upgraded: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.BeginIncrementalUpdate('signed.pdf');
    Upgraded := Pdf.PopulatePAdESLTVEvidence(FetchEvidence,
      THPDFSignatureEvidenceRetryPolicy.Default);
    if Upgraded > 0 then
      // Penyimpanan append-only: byte yang dicakup tanda tangan
      // yang ada dipertahankan verbatim
      Pdf.SaveIncrementalUpdate('signed-lt.pdf');
  finally
    Pdf.Free;
  end;
end;

Kegagalan bersifat per tanda tangan, bukan per dokumen. Responder yang timeout untuk satu penandatangan melewatkan materi penandatangan itu dan menyisakan sisa lintasan utuh, yang merupakan perilaku yang Anda inginkan dalam batch: bukti parsial mengalahkan eksekusi yang dibatalkan, dan return value memberi tahu berapa tanda tangan yang benar-benar membaik

Rantai yang lupa disertakan CMS

Pemeriksaan revokasi membutuhkan sertifikat issuer, dan jumlah stack penandatanganan yang menghilangkan intermediate dari kontainer CMS cukup mengejutkan. Jalur pemulihannya adalah ekstensi Authority Information Access, access method 1.3.6.1.5.5.7.48.2, yang mengiklankan URL tempat sertifikat issuer dapat diunduh. HPDFFetchAIAIntermediates menelusuri URL-URL itu melalui transport yang sama, mem-parse DER dari setiap respons, dan hanya mengembalikan sertifikat yang belum dibawa CMS, dikunci dengan hash DER agar duplikat dan loop tidak dapat berputar

Dua detail menentukan apakah ini bekerja terhadap certificate authority sungguhan. Yang pertama adalah encoding: endpoint CA menyajikan sertifikat sebagai DER telanjang hampir sesering mereka menyajikannya berlapis PEM, dan tidak ada content type yang andal untuk membedakannya. Probe yang tangguh bersifat tekstual, lalu struktural. Cari marker -----BEGIN CERTIFICATE-----, lepas lapisannya dan dekode base64 jika ada, dan di kedua jalur pastikan bahwa byte pertama hasilnya adalah $30, tag DER untuk SEQUENCE. Yang kedua adalah kedalaman: intermediate yang diperoleh bisa jadi sendiri mengiklankan URL AIA untuk issuer-nya, sehingga penelusuran menambahkan kandidat baru ke antrean dan melengkapi rantai yang kurang dua atau tiga hop. Itu harus dibatasi, dan itulah gunanya parameter MaxFetch

Diagram pelengkapan rantai AIA untuk HotPDF: pengambilan URL caIssuers, probe PEM versus DER, deduplikasi hash DER, dan batas kedalaman MaxFetch
HPDFFetchAIAIntermediates menelusuri URL caIssuers melalui transport yang sama, menyelidiki lapisan PEM dan membatasi antrean dengan MaxFetch

Apa itu seed value tanda tangan, dan mengapa ia gagal diam-diam?

Seed value adalah kendala yang dipasangkan penulis dokumen pada signature field untuk memberi tahu penandatangan jenis tanda tangan apa yang dapat diterima: SubFilter yang mana, algoritma digest yang mana, alasan yang mana, versi PDF minimum yang mana, apakah informasi revokasi harus tertanam. Ia berada di dictionary /SV pada field dan didefinisikan di ISO 32000-1 §12.7.5.5. HotPDF menulisnya dengan AttachPAdESSeedValue dan memeriksanya dengan CheckLoadedSignatureSeedValue, yang mengembalikan True ketika field tidak dikendalikan atau setiap kendala yang ada lolos, dan pada False menamai kendala pertama yang gagal melalui parameter output yang bisa Anda masukkan langsung ke pesan error

Mekanisme yang membuat seed value mudah keliru adalah entri flag /Ff yang dijelaskan di §12.7.5.5.3. Bit yang set menandai kendalanya wajib: ketidakcocokan adalah error dan penandatangan harus menolak. Bit yang clear menandai kendala yang sama sebagai preferensi: nilainya menyaring apa yang seharusnya ditawarkan UI dan tidak lebih. Dua jebakan mengikuti dari sana. Pertama, /Ff berada di dalam dictionary /SV, bukan pada widget annotation, sehingga kode yang membaca /Ff level field mendapat jawaban kosong selamanya dan menyimpulkan tidak ada yang dipaksakan. Kedua, penetapan bitnya bukan rangkaian sederhana satu, dua, empat, delapan; di HotPDF writer memancarkan 2 untuk SubFilter, 4 untuk MinVersion, 32 untuk AddRevInfo, dan 64 untuk DigestMethod. Reader yang mengasumsikan bit berurutan mendekode setiap kendala sebagai opsional dan lolos pada setiap uji kecuali uji yang penting

Tabel bit flag seed value untuk penandatanganan PAdES HotPDF yang menampilkan bit Ff 2, 4, 32, dan 64 serta penanganan kendala wajib versus preferensi
Entri /Ff berada di dalam /SV, dan setiap posisi bit menentukan apakah ketidakcocokan adalah penolakan keras atau preferensi UI
var
  Violation: AnsiString;
begin
  // Tanyakan pada field apakah profil yang akan kita pakai
  // menandatangani diizinkan
  if not Pdf.CheckLoadedSignatureSeedValue(0, 'ETSI.CAdES.detached',
       'SHA256', 'Approved for payment', 1, Violation) then
    raise Exception.Create('Signature field rejects this profile: ' +
      String(Violation));
  // Kendala terpenuhi: lanjutkan lintasan penandatanganan
end;

Uji yang membongkar bug dekode semula bukan uji positif. Itu adalah asersi bahwa ketidakcocokan yang dipaksakan harus ditolak, dan itu satu-satunya jenis uji yang dapat menangkap kelas defek ini: dekoder yang membaca dictionary yang salah atau posisi bit yang salah menghasilkan "tidak ada kendala yang dilanggar" untuk setiap input, yang tampak persis seperti perilaku yang benar sampai Anda dengan sengaja melanggar salah satunya

Di mana ini berada di tangga LTV

Empat anak tangga, dan setiap anak tangga membutuhkan yang di bawahnya. B-B adalah tanda tangan telanjang. B-T menambahkan timestamp tepercaya, yang mengunci waktu penandatanganan sehingga validator tahu momen mana yang dipakai untuk mengevaluasi revokasi. B-LT menambahkan bukti revokasi ke DSS, yang diotomatisasi oleh PopulatePAdESLTVEvidence. B-LTA menambahkan timestamp dokumen yang diperbarui sebelum yang sebelumnya melemah, memperpanjang validitas tanpa batas; HotPDF memaparkannya sebagai RenewPAdESLTATimestamp, yang menambahkan timestamp baru sebagai revisi inkremental dan mempertahankan setiap tanda tangan, timestamp, dan entri DSS sebelumnya tanpa disentuh

Model incremental-update adalah satu-satunya cara yang benar untuk menambahkan bukti ke dokumen bertanda tangan, karena menulis ulang berkas akan merusak rentang byte yang dicakup tanda tangan yang ada. Jika Anda perlu menalar apa yang berubah antar revisi, dan apakah perubahan itu termasuk jenis yang diizinkan tanda tangan, analisis itu dibahas terpisah dalam analisis revisi DocMDP dan FieldMDP. Pipeline penandatanganan itu sendiri, termasuk sumber sertifikat dan jebakan urutan byte, ada di panduan penandatanganan PAdES, dan sisi validasi ada di memverifikasi tanda tangan pada dokumen yang dimuat

Satu peringatan praktis tentang urutan. Kumpulkan bukti sesegera mungkin setelah penandatanganan, idealnya dalam pekerjaan yang sama. Responder yang bisa menjawab untuk sebuah sertifikat daring selama sertifikat masih berlaku dan tiada bertahun-tahun kemudian, sehingga dokumen yang keluar dari pipeline Anda sebagai B-B mungkin tidak akan bisa ditingkatkan lagi. HotPDF berjalan sebagai komponen VCL native untuk Delphi dan C++Builder, dan seluruh lintasan bukti berjalan in-process kecuali transport milik Anda sendiri; profil yang didukung tercantum di halaman produk HotPDF Delphi PDF component