Практическое руководство. Подписание XML-документов с помощью цифровых подписей
Обновлен: Ноябрь 2007
Классы пространства имен System.Security.Cryptography.Xml могут использоваться для подписания XML-документа или его части с помощью цифровой подписи. Цифровая подпись XML (XMLDSIG) позволяет устанавливать неизменность данных после подписания. Дополнительные сведения о стандарте XMLDSIG см. в спецификации консорциума W3C, расположенной на веб-узле по адресу: http://www.w3.org/TR/xmldsig-core/.
В следующем примере кода демонстрируется способ создания цифровой подписи для XML-документа и прикрепления подписи к документу, содержащемуся в элементе Signature. В этом примере создается подписывающий ключ RSA, который затем добавляется в безопасный контейнер ключа и используется для подписывания XML-документа. Этот ключ может быть извлечен для проверки цифровой подписи XML, либо может использоваться для подписывания другого XML-документа.
Сведения о проверке цифровой подписи XML, которая была создана с применением данной процедуры, см. в разделе Практическое руководство. Проверка цифровых подписей XML-документов.
Подписывание XML-документа с помощью цифровой подписи
Создайте объект CspParameters и укажите имя контейнера ключа.
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
Создайте симметричный ключ, используя класс RSACryptoServiceProvider. Ключ автоматически сохраняется в контейнере ключа при передаче объекта CspParameters конструктору класса RSACryptoServiceProvider. Этот ключ будет использоваться для подписывания XML-документа.
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
Создайте объект 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");
Создайте новый объект SignedXml и передайте ему объект XmlDocument.
Dim signedXml As New SignedXml(Doc)
SignedXml signedXml = new SignedXml(Doc);
Добавьте подписывающий ключ RSA в объект SignedXml.
signedXml.SigningKey = Key
signedXml.SigningKey = Key;
Создайте объект 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 = "";
Добавьте объект XmlDsigEnvelopedSignatureTransform в объект Reference. Преобразование позволяет проверяющему представлять XML-данные в той же форме, которая использовалась подписывающей стороной. XML-данные могут представляться по-разному, поэтому этот шаг крайне важен для проведения проверки.
Dim env As New XmlDsigEnvelopedSignatureTransform() reference.AddTransform(env)
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env);
Добавьте объект Reference в объект SignedXml.
signedXml.AddReference(reference)
signedXml.AddReference(reference);
Произведите вычисление подписи, вызвав метод ComputeSignature.
signedXml.ComputeSignature()
signedXml.ComputeSignature();
Извлеките XML-представление подписи (элемент Signature) и сохраните его в новый объект XmlElement.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
XmlElement xmlDigitalSignature = signedXml.GetXml();
Присоедините элемент к объекту XmlDocument.
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
Сохраните документ.
xmlDoc.Save("test.xml")
xmlDoc.Save("test.xml");
Пример
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 Doc As XmlDocument, ByVal Key As RSA)
' Check arguments.
If Doc Is Nothing Then
Throw New ArgumentException("Doc")
End If
If Key Is Nothing Then
Throw New ArgumentException("Key")
End If
' Create a SignedXml object.
Dim signedXml As New SignedXml(Doc)
' 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.
Doc.DocumentElement.AppendChild(Doc.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 Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(Doc);
// 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.
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
}
}
В этом примере предполагается, что файл с именем "test.xml" существует в том же каталоге, что и скомпилированная программа. Можно поместить следующий XML-код в файл с именем test.xml и использовать его в данном примере.
<root>
<creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</creditcard>
</root>
Компиляция кода
Для компиляции этого примера может потребоваться включить ссылку на System.Security.dll.
Включите следующие пространства имен: System.Xml, System.Security.Cryptography и System.Security.Cryptography.Xml.
Безопасность
Не следует хранить или передавать закрытый ключ асимметричной пары ключей в виде простого текста. Дополнительные сведения о симметричных и асимметричных криптографических ключах см. в разделе Создание ключей для шифрования и расшифровки.
Не следует внедрять закрытый ключ непосредственно в исходный код. Внедренные ключи могут быть легко прочитаны из сборки с помощью программы Дизассемблер MSIL (Ildasm.exe) или шестнадцатеричного редактора, либо путем открытия сборки в текстовом редакторе, таком как "Блокнот".
См. также
Задачи
Практическое руководство. Проверка цифровых подписей XML-документов
Ссылки
System.Security.Cryptography.Xml