Postupy: Ověření digitálních podpisů dokumentů XML
Třídy v System.Security.Cryptography.Xml oboru názvů můžete použít k ověření dat XML podepsaných digitálním podpisem. Digitální podpisy XML (XMLDSIG) umožňují ověřit, že se data po podepsání nezměnila. Další informace o standardu XMLDSIG naleznete ve specifikaci W3C (World Wide Web Consortium) na adrese https://www.w3.org/TR/xmldsig-core/.
Poznámka:
Kód v tomto článku platí pro Windows.
Příklad kódu v tomto postupu ukazuje, jak ověřit digitální podpis XML obsažený v elementu <Signature
> . Příklad načte veřejný klíč RSA z kontejneru klíčů a pak tento klíč použije k ověření podpisu.
Informace o tom, jak vytvořit digitální podpis, který lze ověřit pomocí této techniky, naleznete v tématu Postupy: Podepisování dokumentů XML pomocí digitálních podpisů.
Ověření digitálního podpisu dokumentu XML
Pokud chcete dokument ověřit, musíte použít stejný asymetrický klíč, který se použil k podepisování. Vytvořte CspParameters objekt a zadejte název kontejneru klíčů, který se použil k podepisování.
CspParameters cspParams = new() { KeyContainerName = "XML_DSIG_RSA_KEY" };
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
Načtěte veřejný klíč pomocí RSACryptoServiceProvider třídy. Klíč se automaticky načte z kontejneru klíčů podle názvu, když předáte CspParameters objekt konstruktoru RSACryptoServiceProvider třídy.
RSACryptoServiceProvider rsaKey = new(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
Vytvořte XmlDocument objekt načtením souboru XML z disku. Objekt XmlDocument obsahuje podepsaný dokument XML k ověření.
XmlDocument xmlDoc = new() { // Load an XML file into the XmlDocument object. PreserveWhitespace = true }; xmlDoc.Load("test.xml");
Dim xmlDoc As New XmlDocument() ' Load an XML file into the XmlDocument object. xmlDoc.PreserveWhitespace = True xmlDoc.Load("test.xml")
Vytvořte nový SignedXml objekt a předejte XmlDocument mu objekt.
SignedXml signedXml = new(xmlDoc);
Dim signedXml As New SignedXml(xmlDoc)
<
signature
> Najděte prvek a vytvořte nový XmlNodeList objekt.XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
Načtěte XML prvního <
signature
> elementu do objektu SignedXml .signedXml.LoadXml((XmlElement?)nodeList[0]);
signedXml.LoadXml(CType(nodeList(0), XmlElement))
Zkontrolujte podpis pomocí CheckSignature metody a veřejného klíče RSA. Tato metoda vrátí logickou hodnotu, která označuje úspěch nebo selhání.
return signedXml.CheckSignature(key);
Return signedXml.CheckSignature(key)
Příklad
Tento příklad předpokládá, že soubor s názvem "test.xml"
existuje ve stejném adresáři jako zkompilovaný program. Soubor "test.xml"
musí být podepsaný pomocí technik popsaných v tématu Postupy: Podepsání dokumentů XML pomocí digitálních podpisů.
using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
[SupportedOSPlatform("Windows")]
public class VerifyXML
{
public static void Main(string[] args)
{
try
{
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new()
{
KeyContainerName = "XML_DSIG_RSA_KEY"
};
// Create a new RSA signing key and save it in the container.
RSACryptoServiceProvider rsaKey = new(cspParams);
// Create a new XML document.
XmlDocument xmlDoc = new()
{
// Load an XML file into the XmlDocument object.
PreserveWhitespace = true
};
xmlDoc.Load("test.xml");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXml(xmlDoc, rsaKey);
// 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 (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static bool VerifyXml(XmlDocument xmlDoc, RSA key)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException(null, nameof(xmlDoc));
if (key == null)
throw new ArgumentException(null, nameof(key));
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new(xmlDoc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count >= 2)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement?)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(key);
}
}
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml
Module VerifyXML
Sub Main(ByVal args() As String)
Try
' Create a new CspParameters object to specify
' a key container.
Dim cspParams As New CspParameters()
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
' Create a new RSA signing key and save it in the container.
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
' Create a new XML document.
Dim xmlDoc As New XmlDocument()
' Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = True
xmlDoc.Load("test.xml")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXml(xmlDoc, rsaKey)
' 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 Exception
Console.WriteLine(e.Message)
End Try
End Sub
' Verify the signature of an XML file against an asymmetric
' algorithm and return the result.
Function VerifyXml(ByVal xmlDoc As XmlDocument, ByVal key As RSA) As [Boolean]
' Check arguments.
If xmlDoc Is Nothing Then
Throw New ArgumentException(
"The XML doc cannot be nothing.", NameOf(xmlDoc))
End If
If key Is Nothing Then
Throw New ArgumentException(
"The key cannot be nothing.", NameOf(key))
End If
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDoc)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
' Throw an exception if no signature was found.
If nodeList.Count <= 0 Then
Throw New CryptographicException("Verification failed: No Signature was found in the document.")
End If
' This example only supports one signature for
' the entire XML document. Throw an exception
' if more than one signature was found.
If nodeList.Count >= 2 Then
Throw New CryptographicException("Verification failed: More that one signature was found for the document.")
End If
' Load the first <signature> node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature(key)
End Function
End Module
Probíhá kompilace kódu
V projektu, který cílí na rozhraní .NET Framework, uveďte odkaz na
System.Security.dll
.V projektu, který cílí na .NET Core nebo .NET 5, nainstalujte balíček NuGet System.Security.Cryptography.Xml.
Zahrňte následující obory názvů: System.Xml, System.Security.Cryptographya System.Security.Cryptography.Xml.
Zabezpečení .NET
Privátní klíč asymetrického páru klíčů nikdy neukládáte ani nepřeneste v prostém textu. Další informace o symetrických a asymetrických kryptografických klíčích najdete v tématu Generování klíčů pro šifrování a dešifrování.
Nikdy nevkládejte privátní klíč přímo do zdrojového kódu. Vložené klíče lze snadno číst ze sestavení pomocí Ildasm.exe (IL Disassembler) nebo otevřením sestavení v textovém editoru, jako je Poznámkový blok.