Postupy: Podepisování dokumentů XML digitálními podpisy

Třídy v System.Security.Cryptography.Xml oboru názvů můžete použít k podepsání dokumentu XML nebo části dokumentu XML 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 v doporučení Xml Wide Web Consortium (W3C) syntaxe a zpracování podpisů XML.

Poznámka:

Kód v tomto článku platí pro Windows.

Příklad kódu v tomto postupu ukazuje, jak digitálně podepsat celý dokument XML a připojit podpis k dokumentu v elementu <Signature> . Příklad vytvoří podpisový klíč RSA, přidá klíč do zabezpečeného kontejneru klíčů a pak tento klíč použije k digitálnímu podepsání dokumentu XML. Klíč pak můžete načíst k ověření digitálního podpisu XML nebo ho můžete použít k podepsání jiného dokumentu XML.

Informace o tom, jak ověřit digitální podpis XML vytvořený pomocí tohoto postupu, naleznete v tématu Postupy: Ověření digitálních podpisů dokumentů XML.

Digitální podepsání dokumentu XML

  1. Vytvořte CspParameters objekt a zadejte název kontejneru klíčů.

    CspParameters cspParams = new()
    {
        KeyContainerName = "XML_DSIG_RSA_KEY"
    };
    
    Dim cspParams As New CspParameters With {
        .KeyContainerName = "XML_DSIG_RSA_KEY"
    }
    
  2. Pomocí třídy vygenerujte asymetrický klíč RSACryptoServiceProvider . Klíč se automaticky uloží do kontejneru klíčů při předání CspParameters objektu konstruktoru RSACryptoServiceProvider třídy. Tento klíč se použije k podepsání dokumentu XML.

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Vytvořte XmlDocument objekt načtením souboru XML z disku. Objekt XmlDocument obsahuje element XML, který se má zašifrovat.

    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")
    
  4. Vytvořte nový SignedXml objekt a předejte XmlDocument mu objekt.

    SignedXml signedXml = new(xmlDoc)
    {
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. Přidejte podpisový klíč RSA do objektu SignedXml .

        SigningKey = rsaKey
    };
    
    signedXml.SigningKey = rsaKey
    
  6. Vytvořte Reference objekt, který popisuje, co se má podepsat. Pokud chcete podepsat celý dokument, nastavte Uri vlastnost na ""hodnotu .

    // Create a reference to be signed.
    Reference reference = new()
    {
        Uri = ""
    };
    
    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
  7. XmlDsigEnvelopedSignatureTransform Přidejte objekt do objektuReference. Transformace umožňuje ověřiteli reprezentovat data XML stejným způsobem jako podepisující osoby. Data XML mohou být reprezentována různými způsoby, takže tento krok je nezbytný pro ověření.

    XmlDsigEnvelopedSignatureTransform env = new();
    reference.AddTransform(env);
    
    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
  8. Reference Přidejte objekt do objektuSignedXml.

    signedXml.AddReference(reference);
    
    signedXml.AddReference(reference)
    
  9. Vypočítá podpis voláním ComputeSignature metody.

    signedXml.ComputeSignature();
    
    signedXml.ComputeSignature()
    
  10. Načtěte reprezentaci XML podpisu ( <Signature> element) a uložte ho do nového XmlElement objektu.

    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
  11. Připojte prvek k objektu XmlDocument .

    xmlDoc.DocumentElement?.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    
  12. Uložte dokument.

    xmlDoc.Save("test.xml");
    
    xmlDoc.Save("test.xml")
    

Příklad

Tento příklad předpokládá, že soubor s názvem test.xml existuje ve stejném adresáři jako zkompilovaný program. Následující kód XML můžete umístit do souboru volaný test.xml a použít ho v tomto příkladu.

<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

Probíhá kompilace kódu

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.

Viz také