Porady: podpisywanie dokumentów XML za pomocą podpisów cyfrowych
Klasy w System.Security.Cryptography.Xml przestrzeni nazw umożliwiają podpisywanie dokumentu XML lub części dokumentu XML 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 zalecenia World Wide Web Consortium (W3C) Składnia i przetwarzanie podpisu XML.
Uwaga
Kod w tym artykule dotyczy systemu Windows.
Przykład kodu w tej procedurze pokazuje, jak cyfrowo podpisać cały dokument XML i dołączyć podpis do dokumentu w elemecie <Signature
> . Przykład tworzy klucz podpisywania RSA, dodaje klucz do bezpiecznego kontenera kluczy, a następnie używa klucza do cyfrowego podpisywania dokumentu XML. Klucz można następnie pobrać, aby zweryfikować podpis cyfrowy XML lub użyć go do podpisania innego dokumentu XML.
Aby uzyskać informacje o sposobie weryfikowania podpisu cyfrowego XML utworzonego przy użyciu tej procedury, zobacz Instrukcje: Weryfikowanie podpisów cyfrowych dokumentów XML.
Aby cyfrowo podpisać dokument XML
CspParameters Utwórz obiekt i określ nazwę kontenera kluczy.
CspParameters cspParams = new() { KeyContainerName = "XML_DSIG_RSA_KEY" };
Dim cspParams As New CspParameters With { .KeyContainerName = "XML_DSIG_RSA_KEY" }
Generowanie klucza asymetrycznego RSACryptoServiceProvider przy użyciu klasy . Klucz jest automatycznie zapisywany w kontenerze kluczy podczas przekazywania CspParameters obiektu do konstruktora RSACryptoServiceProvider klasy. Ten klucz będzie używany do podpisywania dokumentu XML.
RSACryptoServiceProvider rsaKey = new(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
XmlDocument Utwórz obiekt, ładując plik XML z dysku. Obiekt XmlDocument zawiera element XML do zaszyfrowania.
XmlDocument xmlDoc = new() { // Load an XML file into the XmlDocument object. PreserveWhitespace = true }; xmlDoc.Load("test.xml");
' Load an XML file into the XmlDocument object. Dim xmlDoc As New XmlDocument With { .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)
Dodaj klucz RSA podpisywania SignedXml do obiektu .
SigningKey = rsaKey };
signedXml.SigningKey = rsaKey
Utwórz obiekt opisujący Reference , co należy podpisać. Aby podpisać cały dokument, ustaw Uri właściwość na
""
.// Create a reference to be signed. Reference reference = new() { Uri = "" };
' Create a reference to be signed. Dim reference As New Reference() reference.Uri = ""
XmlDsigEnvelopedSignatureTransform Dodaj obiekt do Reference obiektu. Przekształcenie umożliwia weryfikatorowi reprezentowanie danych XML w identyczny sposób, w jaki użyto elementu podpisującego. Dane XML mogą być reprezentowane na różne sposoby, więc ten krok jest niezbędny do weryfikacji.
XmlDsigEnvelopedSignatureTransform env = new(); reference.AddTransform(env);
Dim env As New XmlDsigEnvelopedSignatureTransform() reference.AddTransform(env)
Reference Dodaj obiekt do SignedXml obiektu.
signedXml.AddReference(reference);
signedXml.AddReference(reference)
Oblicz podpis, wywołując metodę ComputeSignature .
signedXml.ComputeSignature();
signedXml.ComputeSignature()
Pobierz reprezentację XML podpisu ( <
Signature
> elementu) i zapisz go w nowym XmlElement obiekcie.XmlElement xmlDigitalSignature = signedXml.GetXml();
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
Dołącz element do XmlDocument obiektu.
xmlDoc.DocumentElement?.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
Zapisz dokument.
xmlDoc.Save("test.xml");
xmlDoc.Save("test.xml")
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. Poniższy kod XML można umieścić w pliku o nazwie test.xml
i użyć go w tym przykładzie.
<root>
<creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</creditcard>
</root>
using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
[SupportedOSPlatform("Windows")]
public class SignXML
{
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");
// Sign the XML document.
SignXml(xmlDoc, rsaKey);
Console.WriteLine("XML file signed.");
// Save the document.
xmlDoc.Save("test.xml");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Sign an XML file.
// This document cannot be verified unless the verifying
// code has the key with which it was signed.
public static void SignXml(XmlDocument xmlDoc, RSA rsaKey)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException(null, nameof(xmlDoc));
if (rsaKey == null)
throw new ArgumentException(null, nameof(rsaKey));
// Create a SignedXml object.
SignedXml signedXml = new(xmlDoc)
{
// Add the key to the SignedXml document.
SigningKey = rsaKey
};
// Create a reference to be signed.
Reference reference = new()
{
Uri = ""
};
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new();
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.
xmlDoc.DocumentElement?.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
}
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml
Module SignXML
Sub Main(ByVal args() As String)
Try
' Create a new CspParameters object to specify
' a key container.
Dim cspParams As New CspParameters With {
.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.
' Load an XML file into the XmlDocument object.
Dim xmlDoc As New XmlDocument With {
.PreserveWhitespace = True
}
xmlDoc.Load("test.xml")
' Sign the XML document.
SignXml(xmlDoc, rsaKey)
Console.WriteLine("XML file signed.")
' Save the document.
xmlDoc.Save("test.xml")
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
' Sign an XML file.
' This document cannot be verified unless the verifying
' code has the key with which it was signed.
Sub SignXml(ByVal xmlDoc As XmlDocument, ByVal rsaKey As RSA)
' Check arguments.
If xmlDoc Is Nothing Then
Throw New ArgumentException(
"The XML doc cannot be nothing.", NameOf(xmlDoc))
End If
If rsaKey Is Nothing Then
Throw New ArgumentException(
"The RSA key cannot be nothing.", NameOf(rsaKey))
End If
' Create a SignedXml object.
Dim signedXml As New SignedXml(xmlDoc)
' Add the key to the SignedXml document.
signedXml.SigningKey = rsaKey
' 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.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
End Sub
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.