💡 Tam çalışan örnek GitHub’da mevcuttur: digital-signing-certificate-validity-dotnet
Denetçi Görene Kadar Kimsenin Görmediği Uyumluluk Sorunu
Bir imzalama hizmeti üç yıl boyunca hatasız çalışır. Belgeler gönderilir, alıcılar kabul eder, günlüklerde soruna işaret eden bir şey yoktur. Sonra bir karşı tarafın doğrulayıcısı bir partiği geçersiz olarak işaretler ve araştırma iki neden bulur: imzalar SHA-1 ile yazılmıştı ve son dört ay boyunca sertifika süresi dolmuştu.
Her iki hata da imzalama anında sessizdi. İşte GroupDocs.Signature 26.9’un değiştirdiği şey bu.
Certificate geçerlilik zorlaması, .NET dijital imzalama için yeni varsayılan davranıştır: geçerlilik süresi dışındaki bir sertifika kullanılmak yerine reddedilir. Bu, iki yardımcıyla birlikte gelir – PDF özeti için varsayılan SHA-256 ve nihayet filtreleyen bir LogLevel – ve birlikte üç hata sınıfını alıcıdan göndericiye taşır, böylece hâlâ düzeltilebilir.
Sessiz Başarının Neden Pahalı Bir Sonuç Olduğu
İmzalama, hatayı yapan tarafın hatayı keşfeden taraf olmaması bakımından alışılmadık bir durumdur. Biçimsiz bir fatura kendi sisteminizde başarısız olur; geçersiz bir imza ise başkasının sisteminde, haftalar sonra, okunabilir bir tanı olmadan başarısız olur.
Bu asimetri, burada “API başarı döndürdü” ifadesinin yararlı bir garanti olmamasının nedenidir. Eski varsayılanlar, çağıranı kesintiye uğratmamaya göre optimize edilmişti ve maliyet alıcıya, sonunda ise yüzlerce belgeyi yeniden imzalamak ve yeniden göndermek zorunda kalan kişiye yansımıştır.
Değişiklik 1: Süresi Dolmuş Sertifikalar Reddedilir
Başlık değişikliği. Sign artık sertifikanın geçerlilik süresi sona erdiğinde veya henüz başlamadığında GroupDocsSignatureException fırlatır ve hiçbir şey diske yazılmaz.
try
{
signature.Sign(outputPath, options);
return true;
}
catch (GroupDocsSignatureException ex)
{
Console.WriteLine($" Rejected: {ex.Message}");
return false;
}
Mesaj, sertifikayı ve onu izin verecek özelliği adlandırır, böylece bir günlük satırını okuyan operatör belgeyi açmadan harekete geçebilir. 26.9’a yükselen ve hataya başlayan bir pipeline için bu neredeyse her zaman nedendir – ve doğru yanıt yenileme, bastırma değil.
Gerçekten eski davranışı ihtiyaç duyduğunuzda, tek bir özellik vardır:
var options = new DigitalSignOptions(certificate)
{
Password = certificatePassword,
AllowExpired = true
};
Belge imzalanır ve bir uyarı logger’a gider. Doğrulayıcılar yine de sonucu reddeder, çünkü AllowExpired kütüphanenin izin verdiği şeyi, sertifikanın değerini değil, belirler. Yardımcı bayrak AllowNotYetValid pencerenin diğer ucunu kapsar ve kasıtlı olarak bağımsızdır: süresi dolmuş bir sertifikaya izin vermek, gelecekte tarihli bir sertifikaya sessizce izin vermek anlamına gelmez.
Değişiklik 2: Varsayılan Olarak SHA-256
PDF dijital imzalar artık mevcut doğrulayıcıların beklediği adbe.pkcs7.detached formatında SHA-256 ile yazılıyor. Önceki sürümler SHA-1 yazıyordu.
var options = new DigitalSignOptions(certificate)
{
Password = certificatePassword,
HashAlgorithm = HashAlgorithm.Sha256,
Reason = "Approved",
Location = "Head office"
};
Özelliği açıkça ayarlamak, yalnızca bir politika gerektirdiğinde Sha384 veya Sha512 gibi daha ileri bir seviyeye gitmek için ya da başka bir şey işleyemeyen bir doğrulayıcı için Sha1‘de kalmak gerektiğinde gereklidir. İmza üzerine eklenen zaman damgası aynı özeti kullanır.
Doğrulama aynı sürümde ve aynı yönde değişti: kriteri olmayan DigitalVerifyOptions önce neredeyse hiçbir şey yapmazdı ve şimdi tam bir kriptografik kontrol gerçekleştiriyor, böylece imzalandıktan sonra değiştirilen bir belge geçersiz olarak raporlanıyor.
Değişiklik 3: LogLevel Gerçekten Filtre Uygular
SignatureSettings uzun süredir bir logger kabul ediyor. 26.9’dan önce seviye göz ardı ediliyordu, bu yüzden her mesaj geliyordu ve çoğu hizmet izlerde boğulmak yerine kaydı kapatıyordu.
Örnek, aynı belgeyi sayıcı bir logger ile üç kez imzalayarak farkı ölçülebilir kılar:
var levels = new Dictionary<string, LogLevel>
{
["None"] = LogLevel.None,
["Warning | Error"] = LogLevel.Warning | LogLevel.Error,
["All"] = LogLevel.All
};
None sıfır mesaj üretir, Warning | Error izin verilen süresi dolmuş sertifika tarafından yükseltilen tek uyarıyı tutar ve All her adım için bir iz ekler. Sayıcı logger kendisi, kendi yığınınız için entegrasyon noktasını oluşturur:
public void Warning(string message)
{
Warnings++;
WarningMessages.Add(message);
}
Bu üç yöntemi Serilog, NLog veya Application Insights ile uygulayın ve kütüphanenin tanılamaları, hizmetinizin diğer günlükleri nereye giderse oraya düşer.
Log seviyesi aldığım istisnaları değiştirir mi?
Hayır ve iki kavramın ilişkili göründüğü için bunu açıkça belirtmek gerekir. LogLevel, ILogger‘a ulaşanları filtreler. İstisnalar kodunuza her durumda fırlatılır: AllowExpired olmadan süresi dolmuş bir sertifika LogLevel.None‘da bile fırlatır ve catch bloğunuz aynı şekilde davranır. Tanılamalar ve kontrol akışı ayrı kanallardır; bu da üretimde Warning | Error ile çalıştırmayı güvenli kılar.
Reddetme Göründüğünden Daha Ucuz
Keskin bir durdurmaya karşı itiraz operasyoneldir: daha önce tamamlanan gece toplu işlemi artık 02:00’de başarısız olur ve birisi uyarılır.
Bu gerçek bir maliyettir ve hâlâ daha küçüğüdür. Reddedilen bir toplu işlem bir uyarı, bir yenileme ve bir yeniden çalıştırma demektir, hepsi kendi sistemleriniz içinde. Süresi dolmuş bir sertifika ile imzalanan bir toplu işlem alıcı tarafından keşfedilir, bu da bir destek konusunu, etkilenen her belgenin yeniden düzenlenmesini ve ne kadar süredir gerçekleştiği hakkında zor bir konuşmayı gerektirir.
Örnek, hatayı teorik olmaktan çıkarıp somutlaştırır: kasıtlı olarak süresi dolmuş bir sertifika ile imzalar, istisnayı yakalar ve mesajı yazdırır, böylece yükseltme üretime geçmeden önce günlüklerinizin tam olarak ne içereceğini görebilirsiniz.
Sürüm artışını planlamadan önce bu yöntemi kendi sertifika mağazanıza karşı çalıştırmanızı öneririm.
Yükseltmeden Önce Ne Yapmalı
Üç kontrol, ne kadar sorun yaratabileceklerine göre sıralanmış.
Her imzalama yolunda, aylık veya üç aylık çalışanları da dahil olmak üzere, sertifika süresinin dolmasını kontrol edin – bunlar süresi dolmuş bir sertifikanın en uzun saklandığı yerlerdir. Ardından HashAlgorithm için grep yapın: eğer hiçbir şey ayarlamamışsa, yükseltmede özetleriniz SHA-1’den SHA-256’ya geçer, bu hâlâ bir sürüm notunda yer alması gereken bir iyileştirmedir. Son olarak, log seviyesini bilinçli olarak belirleyin. Bir hizmet için dürüst varsayılan Warning | Error‘dır; All belirli bir sorunu yeniden üretmek içindir ve None bir imzanın feragat altında yapıldığını söyleyen tek sinyali bırakmak anlamına gelir.
Doğrulama Aynı Yönde Değişti
Kaçırması kolaydır, çünkü çağıran kodda bir şey değiştirmeniz gerekmez. Kriteri olmayan DigitalVerifyOptions önce neredeyse hiçbir şey yapmazdı: verilen kriterleri karşılaştırır ve hiç kriter yoksa söyleyecek pek bir şey yoktu. 26.9’dan itibaren aynı çağrı, her PDF dijital imzanın tam bir kriptografik kontrolünü gerçekleştirir.
Gelen belgeleri doğrulayan bir hizmet için bu, “burada bir imza var” ifadesinden “bu imza bu içeriğe eşleşiyor” ifadesine sessiz bir yükseltmedir. Geçen ay doğrulamadan geçen bir belgenin doğrulamadan başarısız olduğunu görmeden önce bilmek gerekir: belge muhtemelen değiştirilmiştir ve eski kontrol sadece bakmamıştır.
Örnekteki Sertifikalar
Kodu kopyalamaktan ziyade kopyalanmaya değer bir detay: örnek özel anahtar içermez. TestCertificates.cs çalışma zamanında bellekte üç kendinden imzalı PFX oluşturur – geçerli, geçen yıl süresi dolmuş, gelecek yıldan itibaren geçerli – böylece gösterim bugünün tarihi ne olursa olsun çalışır ve depoda hassas bir şey yoktur.
Bu desen, kendi test paketlerinizde benimsenmeye değerdir. Bir taahhüt edilmiş test sertifikası sonunda süresi dolar ve bu olduğunda hata, bu sürümün ortaya çıkarmak için oluşturulduğu hata ile tam olarak aynı görünür.
Sonuç
Üç değişiklik, tek yön: alıcıda ortaya çıkan hatalar artık göndericide ortaya çıkıyor. AllowExpired‘e başvurmadan sertifikayı yenileyin, SHA-256’nın varsayılan olmasına izin verin, gelen belgeleri kriptografik olarak doğrulayın ve ihtiyacınız olmadan önce bir log seviyesi seçin. Örnek, reddetme dahil olmak üzere altı davranışı tek bir geçişte çalıştırır, böylece yükseltme birkaç dakika içinde prova edilebilir.