Aracılığıyla paylaş


System.Security.Cryptography.Xml.SignedXml sınıfı

Bu makale, bu API'nin başvuru belgelerine ek açıklamalar sağlar.

SignedXml sınıfı, XMLDSIG (XML Dijital İmza) olarak da bilinen World Wide Web Konsorsiyumu (W3C) XML İmza Söz Dizimi ve İşleme Belirtimi'nin .NET uygulamasıdır. XMLDSIG, BIR XML belgesinin veya Tekdüzen Kaynak Tanımlayıcısı'ndan (URI) ele alınabilen diğer verilerin tümünü veya bir bölümünü imzalamanın ve doğrulamanın standartlara dayalı, birlikte çalışabilen bir yoludur.

SignedXml Uygulamalar veya kuruluşlar arasında imzalı XML verilerini standart bir şekilde paylaşmanız gerektiğinde sınıfını kullanın. Bu sınıf kullanılarak imzalanan tüm veriler, XMLDSIG için W3C belirtiminin uyumlu herhangi bir uygulaması tarafından doğrulanabilir.

sınıfı, SignedXml aşağıdaki üç tür XML dijital imzası oluşturmanıza olanak tanır:

İmza Türü Açıklama
Zarflı imza İmza, imzalanan XML öğesinin içinde yer alır.
İmzayı sarmalama İmzalı XML öğesinde <Signature> yer alır.
İç ayrılmış imza İmza ve imzalı XML aynı belgede yer alır, ancak öğeden hiçbiri diğerini içermez.

Ayrıca, verilerin ve imzanın ayrı XML belgelerinde yer aldığı dış ayrılmış imza olarak adlandırılan dördüncü bir imza türü de vardır. Dış ayrılmış imzalar sınıfı tarafından SignedXml desteklenmez.

XML imzasının yapısı

XMLDSIG, xml <Signature> belgesinin veya URI'den ele alınabilen diğer verilerin dijital imzalarını içeren bir öğe oluşturur. <Signature> öğesi isteğe bağlı olarak imzayı doğrulayacak bir anahtarın nerede bulunacağı ve imzalama için kullanılan şifreleme algoritması hakkında bilgi içerebilir. Temel yapı aşağıdaki gibidir:

<Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue>Base64EncodedValue==</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>AnotherBase64EncodedValue===</SignatureValue>
</Signature>

Bu yapının ana bölümleri şunlardır:

  • <CanonicalizationMethod> öğesi

    Xml/text öğesinden imza doğrulaması için baytlara yeniden yazma Signature kurallarını belirtir. .NET'teki varsayılan değer, güvenilir bir algoritmayı tanımlayan değeridir http://www.w3.org/TR/2001/REC-xml-c14n-20010315. Bu öğe özelliğiyle SignedInfo.CanonicalizationMethod temsil edilir.

  • <SignatureMethod> öğesi

    içindeki değeri <SignatureValue>üretmek için öğesine uygulanan <Signature> imza oluşturma ve doğrulama için kullanılan algoritmayı belirtir. Önceki örnekte, değer http://www.w3.org/2000/09/xmldsig#rsa-sha1 bir RSA PKCS1 SHA-1 imzası tanımlar. SHA-1 ile ilgili çakışma sorunları nedeniyle Microsoft, SHA-256 veya üzerini temel alan bir güvenlik modeli önerir. Bu öğe özelliğiyle SignatureMethod temsil edilir.

  • <SignatureValue> öğesi

    öğesinin şifreleme imzasını <Signature> belirtir. Bu imza doğrulanmazsa, bloğun <Signature> bir bölümüyle oynanmış ve belge geçersiz kabul edilir. Değer güvenilir olduğu sürece <CanonicalizationMethod> , bu değer kurcalamaya karşı son derece dayanıklıdır. Bu öğe özelliğiyle SignatureValue temsil edilir.

  • URI öğesinin <Reference> özniteliği

    URI başvurusu kullanan bir veri nesnesi belirtir. Bu öznitelik özelliğiyle Reference.Uri temsil edilir.

    • özniteliğini URI belirtmemek, yani özelliğini olarak nullayarlamakReference.Uri, alıcı uygulamanın nesnenin kimliğini bilmesinin beklendiği anlamına gelir. Çoğu durumda, bir null URI bir özel durum oluşturulur. Uygulamanız bunu gerektiren bir null protokolle birlikte çalışmadığı sürece URI kullanmayın.

    • özniteliğini URI boş bir dize olarak ayarlamak, belgenin kök öğesinin imzalandığını gösterir. Bu, zarflı bir imza biçimidir.

    • Özniteliğin URI değeri # ile başlıyorsa, değerin geçerli belgedeki bir öğeye çözümlenmesi gerekir. Bu form desteklenen imza türlerinden herhangi biriyle (zarflı imza, zarflı imza veya iç ayrılmış imza) kullanılabilir.

    • Diğer her şey dış kaynak ayrılmış imzası olarak kabul edilir ve sınıfı tarafından SignedXml desteklenmez.

  • <Transforms> öğesi

    İmzalayanın <Transform> özetlenen veri nesnesini nasıl edindiğini açıklayan sıralı bir öğe listesi içerir. Dönüştürme algoritması kurallı hale getirme yöntemine benzer, ancak öğesini yeniden yazmak <Signature> yerine öğesinin özniteliği <Reference> tarafından URI tanımlanan içeriği yeniden yazar. <Transforms> öğesi sınıfı tarafından TransformChain temsil edilir.

    • Her dönüştürme algoritması, giriş olarak XML (XPath düğüm kümesi) veya bayt alma olarak tanımlanır. Geçerli verilerin biçimi dönüştürme giriş gereksinimlerinden farklıysa dönüştürme kuralları uygulanır.

    • Her dönüştürme algoritması, çıktı olarak XML veya bayt üretme olarak tanımlanır.

    • Son dönüştürme algoritmasının çıkışı bayt cinsinden tanımlanmamışsa (veya hiçbir dönüşüm belirtilmediyse), kurallı hale getirme yöntemi örtük bir dönüşüm olarak kullanılır (öğesinde <CanonicalizationMethod> farklı bir algoritma belirtilse bile).

    • Dönüştürme algoritmasının değeri http://www.w3.org/2000/09/xmldsig#enveloped-signature , öğeyi belgeden kaldır <Signature> olarak yorumlanan bir kuralı kodlar. Aksi takdirde, zarflı imzanın doğrulayıcıları belgeyi özetler, imzayı da içerir, ancak imzalayan belgeyi imza uygulanmadan önce sindirerek farklı yanıtlara yol açar.

  • <DigestMethod> öğesi

    öğesinin özniteliği <Reference> tarafından URI tanımlanan dönüştürülmüş içeriğe uygulanacak özet (şifreleme karması) yöntemini tanımlar. Bu özellik tarafından Reference.DigestMethod temsil edilir.

Kurallı hale getirme yöntemi seçme

Farklı bir değerin kullanılmasını gerektiren bir belirtimle birlikte çalışmadığınız sürece, değeri http://www.w3.org/TR/2001/REC-xml-c14n-20010315olan XML-C14N 1.0 algoritması olan varsayılan .NET kurallılaştırma yöntemini kullanmanızı öneririz. XML-C14N 1.0 algoritmasının tüm XMLDSIG uygulamaları tarafından desteklenmesi gerekir, özellikle de uygulanması örtük bir son dönüşümdür.

Açıklamaları korumayı destekleyen kurallılaştırma algoritmalarının sürümleri vardır. Yorum koruma kurallı hale getirme yöntemleri "görülenleri işaretle" ilkesini ihlal ettiğinden önerilmez. Başka bir ifadeyle, bir <Signature> öğedeki açıklamalar, imzanın nasıl gerçekleştirileceğine ilişkin işlem mantığını değiştirmez, yalnızca imza değerinin ne olduğudur. Zayıf bir imza algoritmasıyla birleştirildiğinde, açıklamaların eklenmesine izin vermek, saldırgana karma çakışmayı zorlamak için gereksiz özgürlük sağlar ve üzerinde oynanmış bir belgenin meşru görünmesini sağlar. .NET Framework'te varsayılan olarak yalnızca yerleşik kurallı oluşturucular desteklenir. Ek veya özel kurallılaştırıcıları desteklemek için özelliğine SafeCanonicalizationMethods bakın. Belge özelliği tarafından SafeCanonicalizationMethods temsil edilen koleksiyonda olmayan bir kurallılaştırma yöntemi kullanıyorsa, CheckSignature yöntemi döndürür false.

Not

Son derece savunma amaçlı bir uygulama, imzalayanların koleksiyondan SafeCanonicalizationMethods kullanmasını beklemediği tüm değerleri kaldırabilir.

Başvuru değerlerinin değiştirilmeleri güvenli mi?

Evet, <Reference> değerler kurcalanmaya karşı güvenlidir. .NET, değerleri ve <SignatureValue> ilişkili dönüşümlerini işlemeden önce hesaplamayı <Reference> doğrular ve kötü amaçlı olabilecek işleme yönergelerini önlemek için erken durdurur.

İmzalayacak öğeleri seçme

Mümkünse özniteliği için URI "" değerini kullanmanızı (veya özelliğini boş bir dize olarak ayarlamanızı Uri ) öneririz. Bu, tüm belgenin özet hesaplaması için dikkate alındığı anlamına gelir ve bu da belgenin tamamının kurcalanmaya karşı korunduğu anlamına gelir.

Id özniteliği "foo" olan bir öğeye başvuruda bulunarak #foo gibi tutturucular biçiminde değerleri görmek URI çok yaygındır. Ne yazık ki, bağlamı değil yalnızca hedef öğenin içeriğini içerdiğinden, üzerinde oynanması kolaydır. Bu ayrımı kötüye kullanarak XML İmza Sarmalama (XSW) olarak bilinir.

Uygulamanız açıklamaların anlamsal olduğunu düşünüyorsa (XML ile çalışırken yaygın değildir), "" yerine "#xpointer(/)" ve "#foo" yerine "#xpointer(id('foo'))" kullanmanız gerekir. #xpointer sürümleri açıklamalar dahil olarak yorumlanırken, kısa ad formları açıklamaları dışlar.

Yalnızca kısmen korunan belgeleri kabul etmeniz gerekiyorsa ve imzanın koruduğu içeriği okuduğundan emin olmak istiyorsanız yöntemini kullanın GetIdElement .

KeyInfo öğesiyle ilgili güvenlik konuları

İmzayı doğrulamak için bir anahtar içeren isteğe bağlı <KeyInfo> öğedeki KeyInfo (yani özelliğindeki) verilere güvenilmemelidir.

Özellikle, değer çıplak bir RSA, DSA veya ECDSA ortak anahtarını temsil ettiğinde KeyInfo , imzanın geçerli olduğunu bildiren yönteme CheckSignature rağmen belge üzerinde oynanmış olabilir. Bu durum, üzerinde değişiklik yapan varlığın yalnızca yeni bir anahtar oluşturması ve üzerinde oynanan belgeyi bu yeni anahtarla yeniden imzalaması gerektiğinden oluşabilir. Bu nedenle, uygulamanız ortak anahtarın beklenen bir değer olduğunu doğrulamadığı sürece, belge üzerinde oynanmış gibi davranılmalıdır. Bu, uygulamanızın belgenin içine eklenmiş ortak anahtarı incelemesini ve belge bağlamı için bilinen değerler listesinde doğrulamasını gerektirir. Örneğin, belgenin bilinen bir kullanıcı tarafından verildiği anlaşılabilseydi, bu kullanıcı tarafından kullanılan bilinen anahtarlar listesinde anahtarı denetlersiniz.

Ayrıca, yöntemi yerine CheckSignature yöntemini kullanarak CheckSignatureReturningKey belgeyi işledikten sonra anahtarı doğrulayabilirsiniz. Ancak en iyi güvenlik için anahtarı önceden doğrulamanız gerekir.

Alternatif olarak, öğesinin içindekileri okumak yerine kullanıcının kayıtlı ortak anahtarlarını denemeyi <KeyInfo> göz önünde bulundurun.

X509Data öğesiyle ilgili güvenlik konuları

İsteğe bağlı <X509Data> öğe öğenin alt <KeyInfo> öğesidir ve X509 sertifikaları için bir veya daha fazla X509 sertifikası veya tanımlayıcısı içerir. öğesindeki <X509Data> verilere de doğal olarak güvenilmemelidir.

Eklenmiş <X509Data> öğeyle belge doğrulanırken, .NET yalnızca verilerin ortak anahtarı belge imzasını doğrulamak için başarıyla kullanılabilen bir X509 sertifikasına çözümlendiğini doğrular. parametresi olarak ayarlanmış falseyöntemi çağırmaktan verifySignatureOnlyCheckSignature farklı olarak iptal denetimi yapılmaz, zincir güveni denetlenemez ve süre sonu doğrulanmaz. Uygulamanız sertifikanın kendisini ayıklayıp parametresi olarak ayarlanmış yöntemine CheckSignatureverifySignatureOnlyfalsegeçirse bile, belge üzerinde değişiklik yapılmasını önlemek için bu doğrulama yeterli değildir. Sertifikanın imzalanan belge için uygun olduğu yine de doğrulanmalıdır.

Katıştırılmış imzalama sertifikası kullanmak, bölümde veya belge içeriğinde <X509Data> yararlı anahtar döndürme stratejileri sağlayabilir. Bu yaklaşımı kullanırken uygulamanın sertifikayı el ile ayıklaması ve aşağıdakine benzer bir doğrulama gerçekleştirmesi gerekir:

  • Sertifika, genel sertifikası uygulamaya eklenmiş olan bir Sertifika Yetkilisi (CA) tarafından doğrudan veya bir zincir üzerinden verildi.

    İşletim sistemi tarafından sağlanan güven listesini bilinen bir konu adı gibi ek denetimler olmadan kullanmak, üzerinde SignedXmloynanmasını önlemek için yeterli değildir.

  • Sertifikanın belge imzalama sırasında süresinin dolmadığı doğrulanır (veya neredeyse gerçek zamanlı belge işleme için "şimdi").

  • ca tarafından verilen ve iptali destekleyen uzun süreli sertifikalar için sertifikanın iptal edilmediğini doğrulayın.

  • Sertifika konusu geçerli belgeye uygun olduğu doğrulanır.

Dönüştürme algoritmasını seçme

Belirli değerleri (XrML gibi) dikte eden bir belirtim ile birlikte çalıştırıyorsanız belirtimi izlemeniz gerekir. Zarflı bir imzanız varsa (örneğin, belgenin tamamını imzalarken) kullanmanız http://www.w3.org/2000/09/xmldsig#enveloped-signature gerekir (sınıf tarafından XmlDsigEnvelopedSignatureTransform temsil edilir). Örtük XML-C14N dönüşümünü de belirtebilirsiniz, ancak gerekli değildir. Zarflama veya ayrılmış imza için dönüştürme gerekmez. Örtük XML-C14N dönüşümü her şeyi halleder.

Microsoft Güvenlik Bülteni MS16-035 tarafından sunulan güvenlik güncelleştirmesiyle, .NET belge doğrulamada varsayılan olarak hangi dönüşümlerin kullanılabileceğini kısıtladı ve güvenilmeyen dönüşümler CheckSignature her zaman döndürülüyorfalse. Özellikle, ek giriş gerektiren dönüşümlere (XML'de alt öğe olarak belirtilen) kötü amaçlı kullanıcıların kötüye kullanımlarına maruz kalmalarından dolayı artık izin verilmiyor. W3C, bu kısıtlamalardan etkilenen iki ana dönüşüm olan XPath ve XSLT dönüşümlerinden kaçınmayı önerir.

Dış başvurularla ilgili sorun

Bir uygulama dış başvuruların geçerli bağlam için uygun göründüğünü doğrulamazsa, bunlar birçok güvenlik açığını (Hizmet Reddi, Dağıtılmış Düşünceler Ion Hizmet Reddi, Bilgilerin Açığa Çıkması, İmzayı Atlama ve Uzaktan Kod Yürütme dahil) sağlayacak şekilde kötüye kullanılabilir. Bir uygulama dış başvuru URI'sini doğrulasa bile, kaynağın iki kez yüklenmesiyle ilgili bir sorun kalır: uygulamanız bunu okuduğunda ve bir kez okuduğunda SignedXml . Uygulama okuma ve belge doğrulama adımlarının aynı içeriğe sahip olduğunu garanti etmediğinden, imza güvenilirlik sağlamaz.

Dış başvuruların riskleri göz önüne alındığında, SignedXml dış başvuruyla karşılaşıldığında bir özel durum oluşturur. Bu sorun hakkında daha fazla bilgi için 3148821 KB makalesine bakın.