İçeriğe geç

İmzalar PDF'de nasıl yer alır

Spec: ETSI EN 319 142-1 Spec: RFC 5652 Evidence: Standard-backed

Bir PDF imzası dosyanın etrafına sarılmaz. İmza, dosyanın içine gömülüdür: imzayı tanımlayan bir sözlük ve imza değerinin kendisini bilerek atlayan, beyan edilmiş bir bayt aralığı üzerinden hesaplanan bir özet. Bu sayfa, bu mekanizmayı ve en az onun kadar önemli olan neyi vaat etmediğini açıklar.

“Belge imzalandı” ifadesi, insanların karar verirken dayandığı bir ifadedir. Bunu bir ödemeyle, bir onayla ya da yasal bir yükümlülükle ilişkilendirirler. Bir imzanın tam olarak hangi baytları kapsadığını bilmiyorsanız, geçerli bir doğrulama sonucunun gerçekte neyi kanıtladığını söyleyemezsiniz. Bir PDF tamamen geçerli bir imza taşıyabilir ve yine de bir okuyucuya imzalayanın hiç görmediği bir içeriği gösterebilir; çünkü o içerik, imzalamadan sonra, imzanın hiçbir zaman üstlenmediği bir bölgeye eklenmiştir. İmzanın yetkisinin nerede başlayıp nerede bittiğini bilmek, savunulabilir bir kararla temenniye dayalı bir karar arasındaki farktır.

  • Bir PDF imzası, harici bir zarf olarak değil, belgenin içindeki bir imza sözlüğünde ve bir imza alanında yer alır.
  • İmzalanan baytlar bir ByteRange dizisiyle beyan edilir: birlikte dosyanın tamamını kapsayan iki (offset, length) bölümü; hariç bırakılan onaltılık imza değeri ise Contents girdisinde tutulur.
  • Uç uca eklenen bu iki bölümün özeti, kriptografik imzanın gerçekte koruduğu şeydir.
  • Daha sonra yeni bir düzeltmeyle eklenen her şey, özgün bayt aralığının dışındadır. Özgün imza geçerli kalır; yeni baytlar hakkında hiçbir zaman iddiada bulunmamıştır.
  • Bir onay imzası ile bir sertifikasyon imzası kapsam bakımından farklıdır: sertifikasyon (DocMDP) sonradan hangi değişikliklere izin verildiğini kısıtlar; onay ise kısıtlamaz.

NextPDF, imzayı biçimin modeline uygun olarak sabit bir sırayla oluşturur; böylece bayt aralığı yaklaşık değil, kesindir.

Motor bir imza yazdığında önce Contents değeri için sabit boyutlu bir yuva ayırır ve sabit genişlikte bir ByteRange yer tutucusu yazar. Motor, çapraz başvuru tablosu ve dosya sonu işareti dâhil olmak üzere belgenin tamamı yazılana kadar bekler. İki gerçek konum değerini ancak o zaman hesaplar, bunları hiçbir baytı kaydırmadan yer tutucuya geri yazar, iki bölümün karmasını alır ve ortaya çıkan CMS nesnesini ayrılmış yuvaya yerleştirir. Yer tutucu, tam olarak, gerçek sayıların doldurulmasının karması alınan baytları hareket ettirememesi için sabit uzunluğa sıfırlarla doldurulur. Kendi içinde tutarlı bir imza üreten tek sıra budur. Motor, bu sıradaki herhangi bir başarısızlığı sessiz bir geri dönüş yerine kesin bir hata olarak ele alır.

PDF 2.0 profili için imza nesnesinin kendisi, ayrık bir CMS SignedData yapısıdır. PDF sözlüğü imzanın nerede bulunduğunu ve nasıl yer aldığını belirtir; CMS nesnesi ise kimin imzaladığını ve kriptografik kanıtı taşır.

  1. Step 1 of 4: ISO 32000-2 §12.8.1 — ByteRange digest & signature dictionary
  2. Step 2 of 4: ISO 32000-2 §12.8.3.3 — ETSI.CAdES.detached SubFilter
  3. Step 3 of 4: ETSI EN 319 142-1 PAdES baseline profile
  4. Step 4 of 4: RFC 5652 CMS SignedData in Contents
Bir PDF imzasının kapsayıcı biçimden kriptografik nesneye kadar nerede tanımlandığı: ISO 32000-2 sözlüğü ve bayt aralığı mekanizmasını belirtir, ETSI EN 319 142-1 bunu PAdES için profiller ve RFC 5652 Contents içine yerleştirilen CMS SignedData nesnesini tanımlar.

Evidence: Standard-backed Mekanizma şurada tanımlanır: Spec: ISO 32000-2, §12.8.1 . Bir bayt aralığı özeti, söz konusu ByteRange girdisinin belirttiği bayt aralığı üzerinden hesaplanır. Bu aralık, imza sözlüğünü içeren ancak imza değerini hariç tutan dosyanın tamamı olmalıdır (imza değeri Contents girdisinde tutulur). ByteRange, tam sayı çiftlerinden oluşan bir dizidir — başlangıç konumu ve uzunluk. Özetin imza değerinin kendisini atlayabilmesi için özellikle bitişik olmayan aralıklar kullanılır.

PDF 2.0 profili için Spec: ISO 32000-2, §12.8.3.3 , SubFilter değeri ETSI.CAdES.detached olduğunda, Contents değerinin DER kodlamalı bir CMS SignedData nesnesi olduğunu belirtir. Bu da Spec: RFC 5652 tarafından tanımlanan yapının aynısıdır; o nesnenin PAdES profili de tam olarak Spec: ETSI EN 319 142-1 tarafından açıklanan profildir.

İmzaların kapsamı tek tip değildir. Spec: ISO 32000-2, §12.7.4.5 , MDP iznini tanımlar: 0 değeri imzayı bir onay imzası yaparken, 13 değerleri onu, daha sonraki hangi değişikliklerin belgeyi uyumlu tuttuğunu kısıtlayan bir sertifikasyon imzası yapar. Aynı bayt aralığı mekanizması vardır; geleceğe ilişkin vaat farklıdır.

NextPDF’in motoru tam olarak bunu uygular: sabit genişlikte bir ByteRange yer tutucusu, iki bölümün uç uca eklenmiş özeti ve yalnızca dosya tamamlandıktan sonra, ayrılmış bir Contents yuvasında sonlandırılan ayrık bir CMS nesnesi.

Bir ByteRange değerini elle oluşturmanız nadiren gerekir. Buradaki örneğin amacı, imzalı bir dosyayı incelediğinizde sonucun tanınabilir olması için biçimini göstermektir.

<?php
declare(strict_types=1);
use NextPDF\Security\Signature\ByteRangeCalculator;
// Offsets the engine knows only after the whole PDF is written:
// $contentsStart — byte just before the '<' of the hex signature
// $contentsEnd — byte just after the '>' that closes it
// $fileLength — total file size in bytes
$range = ByteRangeCalculator::calculate(
contentsStart: $contentsStart,
contentsEnd: $contentsEnd,
fileLength: $fileLength,
);
// $range === [0, $contentsStart, $contentsEnd, $fileLength - $contentsEnd]
// Segment 1: file start → just before the signature value
// Segment 2: just after the signature value → end of file
// The signature value itself is the gap. It is never hashed.
$signedMessage = ByteRangeCalculator::extractSignedData($pdfBytes, $range);
// $signedMessage is segment 1 concatenated with segment 2 — exactly the
// bytes the cryptographic digest is computed over.

İki bölüm arasındaki boşluk, imza değeridir. Kendi özetinin bir parçası olamaz; aralığın bir değil iki parçadan oluşmasının nedeni budur.

Tuzak, geçerli bir imzanın baktığınız dosyanın tamamının imzalandığı anlamına geldiğine inanmaktır. Öyle değildir. Bu, beyan edilen aralığın içindeki baytların bozulmadan kaldığı anlamına gelir. Daha sonraki bir düzeltme, bu aralığın dışına meşru biçimde içerik ekleyebilir — ikinci bir imza, form verisi, doğrulama materyali. İlk imza geçerli kalır ve eklenen içerik hakkında hiçbir şey söylemez. Doğru çalışan bir görüntüleyici, bir imzanın “ekrandaki her baytı” değil, “belgenin imzalama anındaki hâlini” kapsadığını söyler. İkisini bir tutmak, imzalı bir belgenin imzalı görünen imzasız içerik kazanmasının yoludur.

Bu sayfa güveni değil, yapıyı açıklar. Doğru biçimlendirilmiş bir ByteRange ve CMS nesnesi, baytların bozulmadığını ve bunları hangi anahtarın imzaladığını size söyler. Bunlar tek başlarına, o anahtarın düşündüğünüz kişiye ait olup olmadığını, sertifikasının imzalama anında geçerli olup olmadığını ya da daha sonra iptal edilip edilmediğini size söylemez. Bu, sertifika yolu ve iptal denetiminin alanıdır; şurada ele alınır: Bir imzanın doğru biçimde doğrulanması. Bu sayfa ayrıca, imzalamanın ne zaman gerçekleştiğinin herhangi bir bağımsız makamla kanıtlanmasını ele almaz. Kişinin kendi beyan ettiği bir imzalama zamanı, güvenilir zaman değildir — bkz. Zaman damgaları ve güvenilir zaman. NextPDF burada açıklanan yapıyı oluşturur; sertifikalar, güven çıpaları ve zaman damgası makamı, motor tarafından değil, sizin dağıtımınız tarafından sağlanır.

Motorun katmanlara göre sunduğu yetenek, yapı oluşturmadır:

PAdES signature structure (byte range, signature dictionary, detached CMS) — edition availability
Edition Availability
Core

PAdES B-B: imza sözlüğü, sabit genişlikteki ByteRange ve bu sayfada açıklanan ayrık CMS SignedData nesnesi.

Pro

Aynı yapının üzerine PAdES B-T ekler — imza değeri üzerinde güvenilir bir zaman damgası.

Enterprise

Uzun vadeli profilleri ekler (B-LT, B-LTA): gömülü doğrulama materyali ve aynı bayt aralığı temeli üzerine katmanlanan belge zaman damgaları.

  • İmza sözlüğü — imza işleyicisini, SubFilter değerini, ByteRange değerini ve Contents değerini belirten PDF sözlüğü.
  • ByteRange — imza özetinin kapsadığı tam baytları beyan eden (offset, length) tam sayı çiftlerinden oluşan bir dizi.
  • Contents — imza değerini tutan onaltılık girdi (PDF 2.0 için ayrık bir CMS SignedData nesnesi); kendi özetinin dışında bırakılır.
  • CMS SignedData — imzalayanın sertifikasını ve imza baytlarını taşıyan Cryptographic Message Syntax (RFC 5652) yapısı.
  • PAdES — PDF Advanced Electronic Signatures: PDF için CMS imzalarına yönelik, ETSI EN 319 142 serisinde tanımlanan ETSI profili.
  • Onay imzasıMDP izni 0 olan bir imza; içeriği, daha sonraki değişiklikleri kısıtlamadan onaylar.
  • Sertifikasyon imzası — bir DocMDP iznine (MDP 13) sahip, daha sonraki hangi değişikliklerin belgeyi uyumlu tuttuğunu sınırlayan bir imza.