Поделиться через


Практическое руководство. Подписание XML-документов с помощью цифровых подписей

Классы пространства имен System.Security.Cryptography.Xml могут использоваться для подписания XML-документа или его части с помощью цифровой подписи. Цифровая подпись XML (XMLDSIG) позволяет устанавливать неизменность данных после подписания. Дополнительные сведения о стандарте XMLDSIG см. в спецификации консорциума W3C XML Signature Syntax and Processing.

В следующем примере кода демонстрируется способ создания цифровой подписи для XML-документа и прикрепления подписи к документу, содержащемуся в элементе Signature. В этом примере создается подписывающий ключ RSA, который затем добавляется в безопасный контейнер ключа и используется для подписывания XML-документа. Этот ключ может быть извлечен для проверки цифровой подписи XML, либо может использоваться для подписывания другого XML-документа.

Сведения о проверке цифровой подписи XML, которая была создана с применением данной процедуры, см. в разделе Практическое руководство. Проверка цифровых подписей XML-документов.

Подписывание XML-документа с помощью цифровой подписи

  1. Создайте объект CspParameters и укажите имя контейнера ключа.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. Создайте симметричный ключ, используя класс RSACryptoServiceProvider. Ключ автоматически сохраняется в контейнере ключа при передаче объекта CspParameters конструктору класса RSACryptoServiceProvider. Этот ключ будет использоваться для подписывания XML-документа.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Создайте объект XmlDocument путем загрузки XML-файла с диска. Объект XmlDocument содержит XML-элемент, подлежащий шифрованию.

    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
    XmlDocument xmlDoc = new XmlDocument();
    
    // Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = true;
    xmlDoc.Load("test.xml");
    
  4. Создайте новый объект SignedXml и передайте ему объект XmlDocument.

    Dim signedXml As New SignedXml(xmlDoc)
    
    SignedXml signedXml = new SignedXml(xmlDoc);
    
  5. Добавьте подписывающий ключ RSA в объект SignedXml.

    signedXml.SigningKey = Key
    
    signedXml.SigningKey = Key;
    
  6. Создайте объект Reference, определяющий подписываемый документ. Чтобы подписать весь документ, установите для свойства Uri значение "".

    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";
    
  7. Добавьте объект XmlDsigEnvelopedSignatureTransform в объект Reference. Преобразование позволяет проверяющему представлять XML-данные в той же форме, которая использовалась подписывающей стороной. XML-данные могут представляться по-разному, поэтому этот шаг крайне важен для проведения проверки.

    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    
  8. Добавьте объект Reference в объект SignedXml.

    signedXml.AddReference(reference)
    
    signedXml.AddReference(reference);
    
  9. Произведите вычисление подписи, вызвав метод ComputeSignature.

    signedXml.ComputeSignature()
    
    signedXml.ComputeSignature();
    
  10. Извлеките XML-представление подписи (элемент Signature) и сохраните его в новый объект XmlElement.

    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
  11. Присоедините элемент к объекту XmlDocument.

    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
  12. Сохраните документ.

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

Пример

В этом примере предполагается, что файл с именем test.xml существует в том же каталоге, что и скомпилированная программа. Можно поместить следующий XML-код в файл с именем test.xml и использовать его в данном примере.

<root>
    <creditcard>
        <number>19834209</number>
        <expiry>02/02/2002</expiry>
    </creditcard>
</root>
Imports System
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()
            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")
            ' 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 Key As RSA)
        ' Check arguments.
        If xmlDoc Is Nothing Then
            Throw New ArgumentException("xmlDoc")
        End If
        If Key Is Nothing Then
            Throw New ArgumentException("Key")
        End If
        ' Create a SignedXml object.
        Dim signedXml As New SignedXml(xmlDoc)
        ' 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.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    End Sub
End Module
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class SignXML
{

    public static void Main(String[] args)
    {
        try
        {
            // Create a new CspParameters object to specify
            // a key container.
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

            // Create a new RSA signing key and save it in the container. 
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

            // Create a new XML document.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.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 Key)
    {
        // Check arguments.
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // 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.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

    }
}

Компиляция кода

Безопасность

Не следует хранить или передавать закрытый ключ асимметричной пары ключей в виде простого текста. Дополнительные сведения о симметричных и асимметричных криптографических ключах см. в разделе Создание ключей для шифрования и расшифровки.

Не следует внедрять закрытый ключ непосредственно в исходный код. Внедренные ключи могут быть легко прочитаны из сборки с помощью программы Ildasm.exe (дизассемблер MSIL) или шестнадцатеричного редактора, либо путем открытия сборки в текстовом редакторе, таком как "Блокнот".

См. также

Задачи

Практическое руководство. Проверка цифровых подписей XML-документов

Ссылки

System.Security.Cryptography.Xml

Другие ресурсы

Шифрование и цифровые подписи в XML