SignedXml Třída
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Poskytuje obálku základního objektu podpisu XML, který usnadňuje vytváření podpisů XML.
public ref class SignedXml
public class SignedXml
type SignedXml = class
Public Class SignedXml
- Dědičnost
-
SignedXml
Příklady
Následující příklad kódu ukazuje, jak podepsat a ověřit celý dokument XML pomocí obálek podpis.
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
try
{
// Generate a signing key.
RSA Key = RSA.Create();
// Create an XML file to sign.
CreateSomeXml("Example.xml");
Console.WriteLine("New XML file created.");
// Sign the XML that was just created and save it in a
// new file.
SignXmlFile("Example.xml", "signedExample.xml", Key);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml", Key);
// Display the results of the signature verification to
// the console.
if(result)
{
Console.WriteLine("The XML signature is valid.");
}
else
{
Console.WriteLine("The XML signature is not valid.");
}
}
catch(CryptographicException e)
{
Console.WriteLine(e.Message);
}
}
// Sign an XML file and save the signature in a new file. This method does not
// save the public key within the XML file. This file cannot be verified unless
// the verifying code has the key with which it was signed.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key)
{
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Load the passed XML file using its name.
doc.Load(new XmlTextReader(FileName));
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static Boolean VerifyXmlFile(String Name, RSA Key)
{
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
// Create example data to sign.
public static void CreateSomeXml(string FileName)
{
// Create a new XmlDocument object.
XmlDocument document = new XmlDocument();
// Create a new XmlNode object.
XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples");
// Add some text to the node.
node.InnerText = "Example text to be signed.";
// Append the node to the document.
document.AppendChild(node);
// Save the XML document to the file name specified.
XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false));
document.WriteTo(xmltw);
xmltw.Close();
}
}
'
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Public Class SignVerifyEnvelope
Overloads Public Shared Sub Main(args() As [String])
Try
' Generate a signing key.
Dim Key As RSA = RSA.Create()
' Create an XML file to sign.
CreateSomeXml("Example.xml")
Console.WriteLine("New XML file created.")
' Sign the XML that was just created and save it in a
' new file.
SignXmlFile("Example.xml", "signedExample.xml", Key)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml", Key)
' Display the results of the signature verification to
' the console.
If result Then
Console.WriteLine("The XML signature is valid.")
Else
Console.WriteLine("The XML signature is not valid.")
End If
Catch e As CryptographicException
Console.WriteLine(e.Message)
End Try
End Sub
' Sign an XML file and save the signature in a new file. This method does not
' save the public key within the XML file. This file cannot be verified unless
' the verifying code has the key with which it was signed.
Public Shared Sub SignXmlFile(FileName As String, SignedFileName As String, Key As RSA)
' Create a new XML document.
Dim doc As New XmlDocument()
' Load the passed XML file using its name.
doc.Load(New XmlTextReader(FileName))
' Create a SignedXml object.
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
signedXml.SigningKey = Key
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = ""
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
' Compute the signature.
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file against an asymmetric
' algorithm and return the result.
Public Shared Function VerifyXmlFile(Name As [String], Key As RSA) As [Boolean]
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature(Key)
End Function
' Create example data to sign.
Public Shared Sub CreateSomeXml(FileName As String)
' Create a new XmlDocument object.
Dim document As New XmlDocument()
' Create a new XmlNode object.
Dim node As XmlNode = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples")
' Add some text to the node.
node.InnerText = "Example text to be signed."
' Append the node to the document.
document.AppendChild(node)
' Save the XML document to the file name specified.
Dim xmltw As New XmlTextWriter(FileName, New UTF8Encoding(False))
document.WriteTo(xmltw)
xmltw.Close()
End Sub
End Class
Následující příklad kódu ukazuje, jak podepsat a ověřit jeden prvek dokumentu XML pomocí zkosení podpisu.
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
// Generate a signing key.
RSA Key = RSA.Create();
try
{
// Specify an element to sign.
string[] elements = { "#tag1" };
// Sign an XML file and save the signature to a
// new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml");
// Display the results of the signature verification to
// the console.
if (result)
{
Console.WriteLine("The XML signature is valid.");
}
else
{
Console.WriteLine("The XML signature is not valid.");
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear resources associated with the
// RSA instance.
Key.Clear();
}
}
// Sign an XML file and save the signature in a new file.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign)
{
// Check the arguments.
if (FileName == null)
throw new ArgumentNullException("FileName");
if (SignedFileName == null)
throw new ArgumentNullException("SignedFileName");
if (Key == null)
throw new ArgumentNullException("Key");
if (ElementsToSign == null)
throw new ArgumentNullException("ElementsToSign");
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Format the document to ignore white spaces.
doc.PreserveWhitespace = false;
// Load the passed XML file using it's name.
doc.Load(new XmlTextReader(FileName));
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Loop through each passed element to sign
// and create a reference.
foreach (string s in ElementsToSign)
{
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = s;
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
}
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue((RSA)Key));
signedXml.KeyInfo = keyInfo;
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file and return the result.
public static Boolean VerifyXmlFile(String Name)
{
// Check the arguments.
if (Name == null)
throw new ArgumentNullException("Name");
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Format using white spaces.
xmlDocument.PreserveWhitespace = true;
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature();
}
}
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Module SignVerifyEnvelope
Sub Main(ByVal args() As String)
' Generate a signing key.
Dim Key As RSA = RSA.Create()
Try
' Specify an element to sign.
Dim elements As String() = New String() {"#tag1"}
' Sign an XML file and save the signature to a
' new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml")
' Display the results of the signature verification to \
' the console.
If result Then
Console.WriteLine("The XML signature is valid.")
Else
Console.WriteLine("The XML signature is not valid.")
End If
Catch e As CryptographicException
Console.WriteLine(e.Message)
Finally
' Clear resources associated with the
' RSA instance.
Key.Clear()
End Try
End Sub
' Sign an XML file and save the signature in a new file.
Sub SignXmlFile(ByVal FileName As String, ByVal SignedFileName As String, ByVal Key As RSA, ByVal ElementsToSign() As String)
' Check the arguments.
If FileName Is Nothing Then
Throw New ArgumentNullException("FileName")
End If
If SignedFileName Is Nothing Then
Throw New ArgumentNullException("SignedFileName")
End If
If Key Is Nothing Then
Throw New ArgumentNullException("Key")
End If
If ElementsToSign Is Nothing Then
Throw New ArgumentNullException("ElementsToSign")
End If
' Create a new XML document.
Dim doc As New XmlDocument()
' Format the document to ignore white spaces.
doc.PreserveWhitespace = False
' Load the passed XML file using it's name.
doc.Load(New XmlTextReader(FileName))
' Create a SignedXml object.
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
signedXml.SigningKey = Key
' Loop through each passed element to sign
' and create a reference.
Dim s As String
For Each s In ElementsToSign
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = s
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
Next s
' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
Dim keyInfo As New KeyInfo()
keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
signedXml.KeyInfo = keyInfo
' Compute the signature.
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file and return the result.
Function VerifyXmlFile(ByVal Name As String) As [Boolean]
' Check the arguments.
If Name Is Nothing Then
Throw New ArgumentNullException("Name")
End If
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Format using white spaces.
xmlDocument.PreserveWhitespace = True
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature()
End Function
End Module
Poznámky
Třída SignedXml je implementace .NET specifikace XML Signature Syntax and Processing World Wide Web Consortium (W3C), také známá jako XMLDSIG (XML digitální podpis). 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 | Description |
|---|---|
| Obálkový podpis | Podpis je obsažen v elementu XML, který je podepsán. |
| Obálkování 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 SignedXml nepodporuje 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
Signaturez 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 k problémům s kolizemi u 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
URIelementu<Reference>Určuje datový objekt pomocí odkazu na identifikátor URI. Tento atribut je reprezentován Reference.Uri vlastností.
Pokud není specifikován atribut
URI, nastavení vlastnosti Reference.Uri nanullznamená, že přijímající aplikace má znát identitu objektu. Ve většině případůnullURI způsobí vyvolání výjimky. Nepoužívejtenullidentifikátor URI, pokud vaše aplikace nespolupracuje s protokolem, který ho vyžaduje.Nastavením atributu
URIna prázdný řetězec se označuje, že kořenový prvek dokumentu je podepsán, což je forma obaleného podpisu.Pokud hodnota atributu
URIzačí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, obalující podpis nebo interní oddělený podpis).Cokoli jiného se považuje za externí prostředek s odpojeným podpisem a třída SignedXml ho nepodporuje.
Element
<Transforms>Obsahuje uspořádaný seznam prvků
<Transform>, které popisují, jak podepisovatel získal datový objekt, který byl vytvořen. Transformační algoritmus je podobný metodě kanonizace, ale místo přepsání<Signature>prvku přepíše obsah identifikovanýURIatributem<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ěřovatel obálkového podpisu zpracuje dokument, včetně podpisu, ale podepisující by dokument zpracoval před uplatněním podpisu, což by vedlo k rozdílným výsledkům.
Element
<DigestMethod>Identifikuje metodu (kryptografický hash) pro aplikaci na transformovaný obsah identifikovaný atributem
URIprvku<Reference>. 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ářů. Kanonizační metody zachovávající komentáře se nedoporučují, protože porušují princip "podepsat to, 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. Kombinace se slabým podpisovým algoritmem a zahrnutí komentářů dává útočníkovi zbytečnou volnost vyvolat kolizi hash, takže pozměněný dokument vypadá 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í, metoda CheckSignature vrátí false.
Note
Extrémně obranná aplikace může odebrat jakékoli hodnoty, které neočekává, že podepisující osoby budou používat z kolekce SafeCanonicalizationMethods.
Jsou referenční hodnoty bezpečné před manipulací?
Ano, <Reference> hodnoty jsou v bezpečí před manipulací. .NET ověří výpočet <SignatureValue> před zpracováním jakýchkoli <Reference> hodnot a jejich souvisejících transformací a v případě zjištění potenciálně škodlivých instrukcí proces brzy přeruší.
Zvolte prvky, které chcete podepsat.
Pokud je to možné, doporučujeme použít hodnotu "" pro atribut URI (nebo nastavit vlastnost Uri na prázdný řetězec). To znamená, že celý dokument je zohledněn při výpočtu souhrnu, což znamená, že je celý dokument chráněn před neoprávněnou manipulací.
Je velmi běžné vidět URI hodnoty ve formě kotev, jako je #foo, odkazující na prvek, jehož atribut id je "foo". Bohužel je snadné s tím manipulovat, protože to zahrnuje pouze obsah cílového prvku, nikoli kontext. Zneužití tohoto rozdílu je známé 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 jsou interpretovány tak, že zahrnují komentáře, zatímco zkrácené formy je vylučují.
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ý prvek <X509Data> je podřízeným prvkem <KeyInfo> a obsahuje jeden nebo více certifikátů X509 nebo identifikátorů 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 na verifySignatureOnlyfalse, neprovádí se žádná kontrola odvolání, nehodnotí se žádná důvěra v řetězec, a neověřuje se žá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í k zamezení manipulaci v SignedXml.
Certifikát je ověřen, aby nebyl po době podepisování dokumentu (nebo "nyní" pro zpracování dokumentů v téměř reálném čase) propadlý.
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 jako vhodný pro aktuální dokument.
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 podepsaný obálkový podpis (například při podepisování celého dokumentu), musíte použít http://www.w3.org/2000/09/xmldsig#enveloped-signature (reprezentovaný třídou XmlDsigEnvelopedSignatureTransform). Můžete také zadat implicitní XML-C14N transformaci, ale není to nutné. Pro obalující nebo oddělený podpis nejsou vyžadovány žádné transformace. Implicitní transformace XML-C14N se postará o všechno.
S aktualizací zabezpečení zavedenou bulletinem zabezpečení od Microsoftu MS16-035 .NET omezit, jaké transformace je možné použít při ověřování dokumentu ve výchozím nastavení. Nedůvěryhodné transformace způsobují CheckSignature , že se vždy vrátí false. Konkrétně transformace, které vyžadují další vstup (určený jako podřízené prvky v XML), 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 externí odkazy vypadají jako 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é reflexe odepření služby, zpřístupnění informací, obejití podpisu a vzdáleného spuštění kódu). I kdyby aplikace měla ověřit URI externího odkazu, zůstával by problém s tím, že se prostředek načte dvakrát: jednou, když jej čte vaše aplikace, a jednou, když jej čte SignedXml. 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ů vyvolá výjimku při SignedXml výskytu externího odkazu. Další informace o tomto problému najdete v tématu .NET aplikací dochází k chybám výjimek.
Konstruktory
| Name | Description |
|---|---|
| SignedXml() |
Inicializuje novou instanci SignedXml třídy. |
| SignedXml(XmlDocument) |
Inicializuje novou instanci SignedXml třídy ze zadaného dokumentu XML. |
| SignedXml(XmlElement) |
Inicializuje novou instanci SignedXml třídy ze zadaného XmlElement objektu. |
Pole
| Name | Description |
|---|---|
| m_signature | |
| m_strSigningKeyName |
Představuje název nainstalovaného klíče, který se má použít k podepisování objektu SignedXml . |
| XmlDecryptionTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro transformaci dešifrování režimu XML. Toto pole je konstantní. |
| XmlDsigBase64TransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro základní transformaci 64. Toto pole je konstantní. |
| XmlDsigC14NTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro kanonický kód XML transformace. Toto pole je konstantní. |
| XmlDsigC14NWithCommentsTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro kanonické transformace XML s komentáři. Toto pole je konstantní. |
| XmlDsigCanonicalizationUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní kanonický algoritmus digitálních podpisů XML. Toto pole je konstantní. |
| XmlDsigCanonicalizationWithCommentsUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní kanonický algoritmus digitálních podpisů XML a obsahuje komentáře. Toto pole je konstantní. |
| XmlDsigDSAUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní DSA algoritmus digitálních podpisů XML. Toto pole je konstantní. |
| XmlDsigEnvelopedSignatureTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro transformaci obálek podpisu. Toto pole je konstantní. |
| XmlDsigExcC14NTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro výhradní kanonizaci XML. Toto pole je konstantní. |
| XmlDsigExcC14NWithCommentsTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro výhradní kanonizaci XML s komentáři. Toto pole je konstantní. |
| XmlDsigHMACSHA1Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní HMACSHA1 algoritmus digitálních podpisů XML. Toto pole je konstantní. |
| XmlDsigMinimalCanonicalizationUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní minimální kanonický algoritmus pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigNamespaceUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní obor názvů digitálních podpisů XML. Toto pole je konstantní. |
| XmlDsigRSASHA1Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní RSA metodu podpisu pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigRSASHA256Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro variantu RSA metody podpisu SHA-256 pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigRSASHA384Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro variantu RSA metody podpisu SHA-384 pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigRSASHA512Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro variantu RSA metody podpisu SHA-512 pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigSHA1Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní SHA1 metodu digest pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigSHA256Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní SHA256 metodu digest pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigSHA384Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní SHA384 metodu digest pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigSHA512Url |
Představuje identifikátor URI (Uniform Resource Identifier) pro standardní SHA512 metodu digest pro digitální podpisy XML. Toto pole je konstantní. |
| XmlDsigXPathTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro jazyk XPath (XML Path Language). Toto pole je konstantní. |
| XmlDsigXsltTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro transformace XSLT. Toto pole je konstantní. |
| XmlLicenseTransformUrl |
Představuje identifikátor URI (Uniform Resource Identifier) pro algoritmus transformace licencí, který slouží k normalizaci licencí XrML pro podpisy. |
Vlastnosti
| Name | Description |
|---|---|
| EncryptedXml |
Získá nebo nastaví EncryptedXml objekt, který definuje pravidla zpracování šifrování XML. |
| KeyInfo |
Získá nebo nastaví KeyInfo objekt aktuálního SignedXml objektu. |
| Resolver |
Nastaví aktuální XmlResolver objekt. |
| SafeCanonicalizationMethods |
Získá názvy metod, jejichž kanonické algoritmy jsou explicitně povoleny. |
| Signature | |
| SignatureFormatValidator |
Získá delegát, který bude volána k ověření formátu (nikoli kryptografického zabezpečení) podpisu XML. |
| SignatureLength |
Získá délku podpisu pro aktuální SignedXml objekt. |
| SignatureMethod |
Získá signaturu metoda aktuálního SignedXml objektu. |
| SignatureValue |
Získá hodnotu podpisu aktuálního SignedXml objektu. |
| SignedInfo |
SignedInfo Získá objekt aktuálního SignedXml objektu. |
| SigningKey |
Získá nebo nastaví asymetrický algoritmus klíč použitý k podepisování objektu SignedXml . |
| SigningKeyName |
Získá nebo nastaví název nainstalovaného klíče, který se má použít k podepisování objektu SignedXml . |
Metody
| Name | Description |
|---|---|
| AddObject(DataObject) |
DataObject Přidá objekt do seznamu objektů, které se mají podepsat. |
| AddReference(Reference) |
Reference Přidá objekt do objektuSignedXml, který popisuje metodu digest, hodnotu digest a transformaci, která se použije k vytvoření digitálního podpisu XML. |
| CheckSignature() |
Určuje, zda Signature vlastnost ověřuje pomocí veřejného klíče v podpisu. |
| CheckSignature(AsymmetricAlgorithm) |
Určuje, zda Signature vlastnost ověřuje pro zadaný klíč. |
| CheckSignature(KeyedHashAlgorithm) |
Určuje, zda Signature vlastnost ověřuje pro zadaný algoritmus pro ověřovací kód zprávy (MAC). |
| CheckSignature(X509Certificate2, Boolean) |
Určuje, zda Signature vlastnost ověřuje pro zadaný X509Certificate2 objekt a volitelně zda je certifikát platný. |
| CheckSignatureReturningKey(AsymmetricAlgorithm) |
Určuje, zda Signature vlastnost ověřuje pomocí veřejného klíče v podpisu. |
| ComputeSignature() |
Vypočítá digitální podpis XML. |
| ComputeSignature(KeyedHashAlgorithm) |
Vypočítá digitální podpis XML pomocí zadaného algoritmu pro ověřování zpráv (MAC). |
| Equals(Object) |
Určuje, zda je zadaný objekt roven aktuálnímu objektu. (Zděděno od Object) |
| GetHashCode() |
Slouží jako výchozí funkce hash. (Zděděno od Object) |
| GetIdElement(XmlDocument, String) |
XmlElement Vrátí objekt se zadaným ID ze zadaného XmlDocument objektu. |
| GetPublicKey() |
Vrátí veřejný klíč podpisu. |
| GetType() |
Získá Type aktuální instance. (Zděděno od Object) |
| GetXml() |
Vrátí reprezentaci XML objektu SignedXml . |
| LoadXml(XmlElement) |
Načte SignedXml stav z elementu XML. |
| MemberwiseClone() |
Vytvoří mělkou kopii aktuálního Object. (Zděděno od Object) |
| ToString() |
Vrátí řetězec, který představuje aktuální objekt. (Zděděno od Object) |