Porady: sprawdzanie podpisów cyfrowych w dokumentach XML
Klasy w System.Security.Cryptography.Xml przestrzeni nazw umożliwiają weryfikowanie danych XML podpisanych przy użyciu podpisu cyfrowego. Podpisy cyfrowe XML (XMLDSIG) umożliwiają sprawdzenie, czy dane nie zostały zmienione po jego podpisaniu. Aby uzyskać więcej informacji na temat standardu XMLDSIG, zobacz specyfikację World Wide Web Consortium (W3C) pod adresem https://www.w3.org/TR/xmldsig-core/.
Uwaga
Kod w tym artykule dotyczy systemu Windows.
W przykładzie kodu w tej procedurze pokazano, jak zweryfikować podpis cyfrowy XML zawarty w elemecie <Signature
> . Przykład pobiera klucz publiczny RSA z kontenera kluczy, a następnie używa klucza do zweryfikowania podpisu.
Aby uzyskać informacje na temat tworzenia podpisu cyfrowego, który można zweryfikować przy użyciu tej techniki, zobacz Instrukcje: podpisywanie dokumentów XML przy użyciu podpisów cyfrowych.
Aby sprawdzić podpis cyfrowy dokumentu XML
Aby zweryfikować dokument, należy użyć tego samego klucza asymetrycznego, który został użyty do podpisywania. CspParameters Utwórz obiekt i określ nazwę kontenera kluczy, który został użyty do podpisywania.
CspParameters cspParams = new() { KeyContainerName = "XML_DSIG_RSA_KEY" };
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
Pobierz klucz publiczny przy użyciu RSACryptoServiceProvider klasy . Klucz jest automatycznie ładowany z kontenera kluczy według nazwy po przekazaniu CspParameters obiektu do konstruktora RSACryptoServiceProvider klasy.
RSACryptoServiceProvider rsaKey = new(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
XmlDocument Utwórz obiekt, ładując plik XML z dysku. Obiekt XmlDocument zawiera podpisany dokument XML do zweryfikowania.
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")
Utwórz nowy SignedXml obiekt i przekaż XmlDocument do niego obiekt.
SignedXml signedXml = new(xmlDoc);
Dim signedXml As New SignedXml(xmlDoc)
<>
signature
Znajdź element i utwórz nowy XmlNodeList obiekt.XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
Załaduj kod XML pierwszego <
signature
> elementu do SignedXml obiektu.signedXml.LoadXml((XmlElement?)nodeList[0]);
signedXml.LoadXml(CType(nodeList(0), XmlElement))
Sprawdź podpis przy użyciu CheckSignature metody i klucza publicznego RSA. Ta metoda zwraca wartość logiczną wskazującą powodzenie lub niepowodzenie.
return signedXml.CheckSignature(key);
Return signedXml.CheckSignature(key)
Przykład
W tym przykładzie przyjęto założenie, że plik o nazwie "test.xml"
istnieje w tym samym katalogu co skompilowany program. Plik "test.xml"
musi być podpisany przy użyciu technik opisanych w temacie Instrukcje: podpisywanie dokumentów XML przy użyciu podpisów cyfrowych.
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
Kompilowanie kodu
W projekcie przeznaczonym dla programu .NET Framework dołącz odwołanie do
System.Security.dll
elementu .W projekcie przeznaczonym dla platformy .NET Core lub .NET 5 zainstaluj pakiet NuGet System.Security.Cryptography.Xml.
Uwzględnij następujące przestrzenie nazw: System.Xml, System.Security.Cryptographyi System.Security.Cryptography.Xml.
Zabezpieczenia platformy .NET
Nigdy nie przechowuj ani nie przesyłaj klucza prywatnego pary kluczy asymetrycznych w postaci zwykłego tekstu. Aby uzyskać więcej informacji na temat symetrycznych i asymetrycznych kluczy kryptograficznych, zobacz Generowanie kluczy szyfrowania i odszyfrowywania.
Nigdy nie osadzaj klucza prywatnego bezpośrednio w kodzie źródłowym. Klucze osadzone można łatwo odczytać z zestawu przy użyciu Ildasm.exe (dezasembler IL) lub otwierając zestaw w edytorze tekstów, takim jak Notatnik.