System.Security.Cryptography.Xml.SignedXml – třída
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Třída SignedXml je implementace rozhraní .NET syntaxe a zpracování syntaxe a zpracování xml konsorcia W3C (World Wide Web Consortium), která se označuje také jako XMLDSIG (digitální podpis XML). XMLDSIG je interoperabilní způsob podepisování a ověřování všech nebo částí dokumentu XML nebo jiných dat, která je adresovatelná z identifikátoru URI (Uniform Resource Identifier).
SignedXml Třídu používejte vždy, když potřebujete sdílet podepsaná data XML mezi aplikacemi nebo organizacemi standardním způsobem. Všechna data podepsaná pomocí této třídy lze ověřit jakoukoli implementací odpovídající specifikace W3C pro XMLDSIG.
Třída SignedXml umožňuje vytvořit následující tři druhy digitálních podpisů XML:
Typ podpisu | Popis |
---|---|
Obálkový podpis | Podpis je obsažen v elementu XML, který je podepsán. |
Zkosení podpisu | Podepsaný KÓD XML je obsažen v elementu <Signature> . |
Interní odpojený podpis | Podpis a podepsaný XML jsou ve stejném dokumentu, ale žádný prvek neobsahuje druhý prvek. |
Existuje také čtvrtý druh podpisu nazývaného externí odpojený podpis, což je, když jsou data a podpis v samostatných dokumentech XML. Třída nepodporuje SignedXml externí odpojené podpisy.
Struktura podpisu XML
XMLDSIG vytvoří <Signature>
prvek, který obsahuje digitální podpis dokumentu XML nebo jiná data, která lze adresovat z identifikátoru URI. Prvek <Signature>
může volitelně obsahovat informace o tom, kde najít klíč, který ověří podpis a který kryptografický algoritmus byl použit k podepisování. Základní struktura je následující:
<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>
Hlavní části této struktury jsou:
Element
<CanonicalizationMethod>
Určuje pravidla pro přepsání elementu
Signature
z XML/textu do bajtů pro ověření podpisu. Výchozí hodnota v .NET je http://www.w3.org/TR/2001/REC-xml-c14n-20010315, která identifikuje důvěryhodný algoritmus. Tento prvek je reprezentován SignedInfo.CanonicalizationMethod vlastností.Element
<SignatureMethod>
Určuje algoritmus použitý pro generování a ověřování podpisu, který byl použit pro
<Signature>
prvek k vytvoření hodnoty v<SignatureValue>
. V předchozím příkladu hodnota http://www.w3.org/2000/09/xmldsig#rsa-sha1 identifikuje podpis SHA-1 PKCS1 RSA. Vzhledem ke kolizím problémů s SHA-1 microsoft doporučuje model zabezpečení založený na algoritmu SHA-256 nebo lepším. Tento prvek je reprezentován SignatureMethod vlastností.Element
<SignatureValue>
Určuje kryptografický podpis prvku
<Signature>
. Pokud tento podpis neověří, některá část<Signature>
bloku byla manipulována a dokument je považován za neplatný.<CanonicalizationMethod>
Pokud je hodnota důvěryhodná, je tato hodnota vysoce odolná vůči manipulaci. Tento prvek je reprezentován SignatureValue vlastností.Atribut
URI
elementu<Reference>
Určuje datový objekt pomocí odkazu na identifikátor URI. Tento atribut je reprezentován Reference.Uri vlastností.
Nezadávejte
URI
atribut, tj. nastavení Reference.Uri vlastnostinull
na , znamená, že přijímající aplikace má znát identitu objektu. Ve většině případůnull
dojde k vyvolání výjimky identifikátorem URI. Nepoužívejtenull
identifikátor URI, pokud vaše aplikace nespolupracuje s protokolem, který ho vyžaduje.Nastavení atributu
URI
na prázdný řetězec označuje, že kořenový prvek dokumentu je podepsán, což je forma obálek podpis.Pokud hodnota atributu
URI
začíná znakem #, musí se hodnota přeložit na prvek v aktuálním dokumentu. Tento formulář lze použít s libovolnými podporovanými typy podpisů (obálkový podpis, zkosení podpisu nebo interní odpojený podpis).Cokoli jiného se považuje za externí podpis odpojeného prostředku a třída ho SignedXml nepodporuje.
Element
<Transforms>
Obsahuje uspořádaný
<Transform>
seznam prvků, které popisují, jak podepisující objekt získal datový objekt, který byl uložen. Transformační algoritmus je podobný metodě kanonizace, ale místo přepsání<Signature>
prvku přepíše obsah identifikovanýURI
atributem<Reference>
prvku. Prvek<Transforms>
je reprezentován TransformChain třídou.Každý transformační algoritmus je definován tak, že jako vstup přebírá xml (sadu uzlů XPath) nebo bajty. Pokud se formát aktuálních dat liší od požadavků na vstup transformace, použijí se pravidla převodu.
Každý transformační algoritmus je definován jako produkce XML nebo bajtů jako výstup.
Pokud výstup posledního transformačního algoritmu není definován v bajtech (nebo nebyly zadány žádné transformace), použije se metoda kanonizace jako implicitní transformace (i když byl v
<CanonicalizationMethod>
prvku zadán jiný algoritmus).Hodnota transformačního http://www.w3.org/2000/09/xmldsig#enveloped-signature algoritmu kóduje pravidlo, které je interpretováno jako odebrání
<Signature>
prvku z dokumentu. V opačném případě ověří obálkový podpis dokument, včetně podpisu, ale podepisující by dokument před uplatněním podpisu vyhodnotil, což vede k různým odpovědím.
Element
<DigestMethod>
Identifikuje metodu hash (kryptografická hodnota hash), která se použije na transformovaný obsah identifikovaný
URI
atributem<Reference>
prvku. Tato vlastnost je reprezentována Reference.DigestMethod vlastností.
Volba metody kanonizace
Pokud nespolupracuje se specifikací, která vyžaduje použití jiné hodnoty, doporučujeme použít výchozí metodu kanonizace .NET, což je algoritmus XML-C14N 1.0, jehož hodnota je http://www.w3.org/TR/2001/REC-xml-c14n-20010315. Algoritmus XML-C14N 1.0 musí být podporován všemi implementacemi XMLDSIG, zejména proto, že se jedná o implicitní konečnou transformaci, která se má použít.
Existují verze algoritmů kanonizace, které podporují zachování komentářů. Metody kanonizace pro zachování komentářů se nedoporučuje, protože porušují princip "znamení, co je vidět". To znamená, že komentáře v <Signature>
prvku nezmění logiku zpracování způsobu provedení podpisu, pouze to, co je hodnota podpisu. Když se zkombinuje se slabým podpisovým algoritmem, umožní zahrnutí komentářů útočníkovi nepotřebnou svobodu vynutit kolize hash a zfalšovaný dokument se zobrazí jako legitimní. V rozhraní .NET Framework jsou ve výchozím nastavení podporovány pouze předdefinované kanonizátory. Pokud chcete podporovat další nebo vlastní kanonizační metody, podívejte se na SafeCanonicalizationMethods vlastnost. Pokud dokument používá kanonizační metodu, která není v kolekci reprezentovaná SafeCanonicalizationMethods vlastností, CheckSignature vrátí false
metoda .
Poznámka:
Extrémně obranná aplikace může odebrat jakékoli hodnoty, které neočekává, že podepisující osoby budou z SafeCanonicalizationMethods kolekce používat.
Jsou referenční hodnoty bezpečné před manipulací?
Ano, <Reference>
hodnoty jsou v bezpečí před manipulací. .NET před zpracováním jakýchkoli <Reference>
hodnot a souvisejících transformací ověří <SignatureValue>
výpočet a brzy se přeruší, aby se zabránilo potenciálně škodlivému zpracování instrukcí.
Zvolte prvky, které chcete podepsat.
Pokud je to možné, doporučujeme pro atribut použít hodnotu "" URI
(nebo nastavit Uri vlastnost na prázdný řetězec). To znamená, že celý dokument se považuje za výpočet hodnot hash, což znamená, že celý dokument je chráněn před manipulací.
Je velmi běžné vidět URI
hodnoty ve formě ukotvení, jako je #foo, odkazující na prvek, jehož ATRIBUT ID je "foo". Bohužel je to snadné, protože to zahrnuje pouze obsah cílového prvku, nikoli kontext. Tento rozdíl se označuje jako XSW (XML Signature Wrapping).
Pokud vaše aplikace považuje komentáře za sémantické (což není běžné při práci s XML), měli byste místo "#foo" použít "#xpointer(/)" a "#xpointer(id('foo')". Verze #xpointer se interpretují jako zahrnutí komentářů, zatímco zkrácené formuláře s výjimkou komentářů.
Pokud potřebujete přijmout dokumenty, které jsou pouze částečně chráněné a chcete zajistit, abyste četli stejný obsah, který je chráněný podpisem, použijte metodu GetIdElement .
Důležité informace o zabezpečení elementu KeyInfo
Data v volitelném <KeyInfo>
prvku (tj KeyInfo . vlastnost), která obsahuje klíč k ověření podpisu, by neměla být důvěryhodná.
Konkrétně pokud KeyInfo hodnota představuje holý RSA, DSA nebo ECDSA veřejný klíč, dokument mohl být manipulován, i když CheckSignature metoda hlásí, že podpis je platný. K tomu může dojít, protože entita, která manipuluje, musí vygenerovat nový klíč a znovu podepsat zfalšovaný dokument s tímto novým klíčem. Pokud tedy aplikace nevěří, že veřejný klíč má očekávanou hodnotu, měl by se dokument považovat za manipulovaný. To vyžaduje, aby aplikace prozkoumala veřejný klíč vložený v dokumentu a ověřila ho v seznamu známých hodnot pro kontext dokumentu. Pokud je například možné, že dokument vydá známý uživatel, zkontrolujete klíč na seznamu známých klíčů používaných tímto uživatelem.
Klíč můžete také ověřit po zpracování dokumentu pomocí CheckSignatureReturningKey metody místo CheckSignature metody. Pokud ale chcete zajistit optimální zabezpečení, měli byste klíč ověřit předem.
Alternativně zvažte možnost vyzkoušet zaregistrované veřejné klíče uživatele místo čtení toho, co je v <KeyInfo>
prvku.
Důležité informace o zabezpečení elementu X509Data
Volitelný <X509Data>
prvek je podřízený <KeyInfo>
prvek a obsahuje jeden nebo více certifikátů nebo identifikátorů X509 pro certifikáty X509. Data v <X509Data>
prvku by také neměla být ze své podstaty důvěryhodná.
Při ověřování dokumentu pomocí vloženého <X509Data>
prvku .NET ověří pouze to, že se data přeloží na certifikát X509, jehož veřejný klíč lze úspěšně použít k ověření podpisu dokumentu. Na rozdíl od volání CheckSignature metody s parametrem nastaveným verifySignatureOnly
na false
, neprovádí se žádná kontrola odvolání, není zaškrtnuto žádný vztah důvěryhodnosti řetězu a není ověřeno žádné vypršení platnosti. I když vaše aplikace extrahuje samotný certifikát a předá CheckSignature ho metodě s parametrem verifySignatureOnly
nastaveným na false
, to stále není dostatečné ověření, aby se zabránilo manipulaci s dokumentem. Certifikát je stále potřeba ověřit podle toho, jak je vhodný pro podepsaný dokument.
Použití vloženého podpisového certifikátu může poskytovat užitečné strategie obměně klíčů, ať už v oddílu <X509Data>
nebo v obsahu dokumentu. Při použití tohoto přístupu by aplikace měla certifikát extrahovat ručně a provést ověření podobné:
Certifikát byl vydán přímo nebo prostřednictvím řetězu certifikační autoritou (CA), jejíž veřejný certifikát je vložen do aplikace.
Použití seznamu důvěryhodnosti poskytnutého operačním systémem bez dalších kontrol, jako je známý název subjektu, není dostačující, aby se zabránilo SignedXmlmanipulaci .
Certifikát je ověřený tak, že v době podepisování dokumentu nevypršela platnost (nebo "nyní" pro téměř zpracování dokumentů v reálném čase).
U dlouhodobých certifikátů vydaných certifikační autoritou, která podporuje odvolání, ověřte, že certifikát nebyl odvolán.
Subjekt certifikátu je ověřen podle potřeby aktuálního dokumentu.
Volba transformačního algoritmu
Pokud spolupracujete se specifikací, která diktovala konkrétní hodnoty (například XrML), musíte postupovat podle specifikace. Pokud máte obálek podpis (například při podepisování celého dokumentu), musíte použít http://www.w3.org/2000/09/xmldsig#enveloped-signature (reprezentovaný XmlDsigEnvelopedSignatureTransform třídou). Můžete také zadat implicitní transformaci XML-C14N, ale není to nutné. Pro zkosení nebo odpojení podpisu nejsou vyžadovány žádné transformace. Implicitní transformace XML-C14N se postará o všechno.
S aktualizací zabezpečení zavedenou bulletinem zabezpečení společnosti Microsoft MS16-035 technologie .NET omezila, jaké transformace lze použít při ověřování dokumentu ve výchozím nastavení s nedůvěryhodnými transformacemi, které způsobují CheckSignature vždy vrácení false
. Transformace, které vyžadují další vstup (určené jako podřízené prvky v XML), již nejsou povoleny kvůli jejich citlivosti zneužití škodlivými uživateli. W3C doporučuje vyhnout se transformacíM XPath a XSLT, což jsou dvě hlavní transformace ovlivněné těmito omezeními.
Problém s externími odkazy
Pokud aplikace neověřuje, že se externí odkazy zdají být vhodné pro aktuální kontext, mohou být zneužity způsoby, které poskytují mnoho ohrožení zabezpečení (včetně odepření služby, distribuovaného Reflexe ion odepření služby, zpřístupnění informací, obejití podpisu a vzdáleného spuštění kódu). I když aplikace ověřila identifikátor URI externího odkazu, zůstal by problém s načtením prostředku dvakrát: jednou při čtení aplikace a jednou při SignedXml čtení. Vzhledem k tomu, že neexistuje žádná záruka, že kroky ověření dokumentu a čtení aplikace mají stejný obsah, podpis neposkytuje důvěryhodnost.
Vzhledem k rizikům externích odkazů SignedXml dojde při výskytu externího odkazu k výjimce. Další informace o tomto problému najdete v článku znalostní báze 3148821.