· kaynak dev.to (home feed)
PDF sıkıştırma araçları dijital imzaları bozuyor veya siliyor; beş araçlı test bunu ortaya koydu
dev.to'daki iki deney, yaygın PDF sıkıştırma araçlarının dijital imzaları geçersiz kıldığını veya iz bırakmadan sildiğini; pdfsig'nin ise yalnızca imzalı baytların hash'ini kontrol ettiği için düzenlenmiş imzalı bir PDF'yi geçerli olarak raporlayabildiğini gösteriyor.

18 Ekim'de dev.to'da yayımlanan iki eş deney, dijital olarak imzalanmış bir PDF'yi beş yaygın sıkıştırma veya yeniden yazma aracından herhangi birine vermenin imzayı ya geçersiz kıldığını ya da iz bırakmadan kaldırdığını ortaya koydu. Testler ayrıca bir doğrulama boşluğunu da gün yüzüne çıkardı: poppler'ın pdfsig aracı, sayfa içeriği değiştirilmiş imzalı bir PDF'yi geçerli olarak raporlayabiliyor, çünkü yalnızca orijinalde imzalanmış baytlar üzerindeki hash'i kontrol ediyor.
İmzalar sayfayı değil, baytları korur
Yazılara göre (pm_cheng ve iterandum), yazar 1800×1200 boyutlu yapay bir fotoğraf içeren tek sayfalık kurgusal bir sözleşme hazırladı, pyHanko ile kendi oluşturduğu bir test sertifika otoritesi kullanarak imzaladı ve 931.980 baytlık sonucu poppler'ın pdfsig 26.08.0 ve pyHanko 0.33.0 araçlarıyla kontrol etti. İmzanın ByteRange değeri [0 923749 931275 705] idi: bir doğrulayıcı ilk 923.749 baytı ve 705 baytlık bir kuyruğu hash'ler, hex olarak kodlanmış imza değerinin bulunduğu aralığı atlar ve ikinci aralık tam olarak dosyanın sonunda biter.
İmza ham baytlar üzerinde bir hash olduğu için, nesneleri yeniden sıralamak veya tek bir stream'i yeniden sıkıştırmak bile imzayı bozar; oluşturulan sayfadaki her karakter birebir aynı görünse bile.
Beş araç, beş bozuk ya da kaybolmuş imza
Test edilen her araç dosyanın tamamını yeniden yazdı. Çıktıların hiçbiri orijinal baytlarla başlamıyordu ve her biri iki %%EOF işaretçisinden birine indi.
| Araç | Çıktı boyutu | İmza alanı |
|---|---|---|
| qpdf (düzen yeniden yazma) | 930.748 B | korunmuş, ByteRange değiştirilmeden kopyalanmış |
| qpdf (nesne stream'leri) | 930.178 B | korunmuş |
| Ghostscript /ebook | 39.876 B | tamamen silinmiş |
| ImgIng (ebook ön ayarı) | 64.903 B | korunmuş, aralık hâlâ 931.980'de bitiyor |
| iLovePDF (önerilen) | 37.513 B | tamamen silinmiş |
| PDF24 (varsayılan) | 50.877 B | korunmuş, ByteRange kopyalanmış |
pdfsig, imza sözlüğünü koruyan her çıktıyı "Illegal values in ByteRange array" hatasıyla reddetti ve pyHanko hepsini INVALID olarak işaretledi. Ghostscript ve iLovePDF imza alanını tamamen sildi ve doğrulanacak bir şey bırakmadı. Yazar, sessizce silinmenin daha kötü sonuç olduğunu savunuyor: okuyucu bozuk bir imza konusunda uyarılabilir, ancak alan bir kez gittikten sonra dosya hiç imzalanmamış bir dosyadan ayırt edilemez görünür.
pdfsig düzenlemelerden sonra bile geçerli dedi
İmzalı bir PDF'yi değiştirmenin meşru yolu artımlı güncellemedir; bu yöntem orijinal baytlara dokunmadan yeni nesneler, bir çapraz referans tablosu ve son bir %%EOF ekler. Yazar üç böyle revizyon ekledi: ikinci bir imza, pypdf ile yazılmış bir metin açıklaması ve pyHanko ile eklenmiş fazladan bir sayfa içeriği satırı. pdfsig üçü için de "Signature is Valid" raporladı ve yalnızca içerik değişikliği için "Not total document signed" notunu ekledi.
pyHanko daha da ileri giderek imza sonrası revizyonları PDF'nin değişiklik kurallarıyla (DocMDP ve FieldMDP) karşılaştırdı. İkinci imza için kabul edilebilir değişiklik kararı verdi, ancak içerik düzenlemesi için ILLEGAL_MODIFICATIONS döndürdü. Açıklama da işaretlendi; ancak yazar bunun pyHanko'nun varsayılan ilkesinin pypdf'nin açıklamaları ekleme biçimini ("unexplained xrefs") tanımamasından kaynaklanabileceğini, Acrobat'nın göstereceğinden değil konusunda uyarıyor; Acrobat test edilmedi.
Temel ders: eşleşen bir hash, imzalı baytların bozulmamış olduğunu kanıtlar. Sonradan ne eklendiği konusunda hiçbir şey söylemez.
Ucuz bir kontrol: ByteRange sonu ile dosya boyutu karşılaştırması
Eş yazıda, pypdf 6.20.1 ile oluşturulan ve her imzanın son ByteRange ofsetini dosya boyutuyla karşılaştıran bir dedektör anlatılıyor. Eşleşiyorlarsa imza her şeyi kapsıyordur. Aralık erken bitiyorsa imzadan sonra revizyonlar eklenmiştir. Dosyanın ötesinde bitiyorsa dosya yeniden yazılmış ve imza sözlüğü eski sayılarla taşınmıştır.
Testte, üç artımlı güncelleme de "eklenmiş" olarak döndü; qpdf, ImgIng ve PDF24'ün alanı koruyan yeniden yazımları "EOF sonrası" olarak döndü; Ghostscript ve iLovePDF çıktıları ise imza alanları silinmiş olduğu için hiçbir şey döndürmedi. Yazar sınırları da not ediyor: dosyayı büyüten bir yeniden yazım "eklenmiş" dalına düşerdi ve %%EOF işaretçilerini saymak (artımlı dosyalarda üç, her yeniden yazımda bir) iki durumu ayırt edebilir.
Bu kontrol artık bir yükleme servisini yönlendiriyor: imzası dosyanın tamamını kapsayan dosyalar olduğu gibi saklanıyor ve asla sıkıştırılmıyor; eklemeli dosyalar saklanıyor ve insan incelemesi için işaretleniyor; aralıkları dosya sonunun ötesinde biten dosyalar yükleyene geri gönderiliyor ve yalnızca imzasız dosyalar sıkıştırılıyor. Sıkıştırma zaten artımlı yolu izleyemez, çünkü bir güncelleme her orijinal baytı korumak zorundadır; dolayısıyla dosya yalnızca büyüyebilir.
Neden önemli
Önce imzalayıp sonra sıkıştıran e-sözleşme hatları kendi kanıtlarını sessizce yok ediyor. Deneyler üç farklı başarısızlık biçimini belgeliyor: sesli biçimde bozulan imzalar, sessizce kaybolan imzalar ve yalnızca belgenin bir kısmını kapsarken geçerli görünen imzalar. Standart doğrulama araçları bu durumları kendi başlarına ayırt etmiyor ve bir bayt-hash denetleyicisinden gelen "geçerli" kararı, imzadan sonra hiçbir şeyin değişmediğinin kanıtı değil. Çözümler ucuz: imzadan sonra değil önce sıkıştırın, imzalı dosyaları sıkıştırıcılardan tamamen uzak tutun ve hash kontrollerini revizyon farkındalıklı bir doğrulayıcıyla ya da en azından ByteRange-dosya boyutu karşılaştırmasıyla eşleştirin.
- #digital-signatures
- #compression
- #pdfsig
- #pyhanko