SignedXml クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
コア XML 署名オブジェクトのラッパーを提供して、XML 署名の作成を容易にします。
public ref class SignedXml
public class SignedXml
type SignedXml = class
Public Class SignedXml
- 継承
-
SignedXml
例
次のコード例は、エンベロープ署名を使用して XML ドキュメント全体に署名して検証する方法を示しています。
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
#using <System.Security.dll>
#using <System.Xml.dll>
using namespace System;
using namespace System::Security::Cryptography;
using namespace System::Security::Cryptography::X509Certificates;
using namespace System::Security::Cryptography::Xml;
using namespace System::Text;
using namespace System::Xml;
// Sign an XML file and save the signature in a new file. This method does not
// save the public key within the XML file. This file cannot be verified unless
// the verifying code has the key with which it was signed.
void SignXmlFile( String^ FileName, String^ SignedFileName, RSA^ Key )
{
// Create a new XML document.
XmlDocument^ doc = gcnew XmlDocument;
// Load the passed XML file using its name.
doc->Load( gcnew XmlTextReader( FileName ) );
// Create a SignedXml object.
SignedXml^ signedXml = gcnew SignedXml( doc );
// Add the key to the SignedXml document.
signedXml->SigningKey = Key;
// Create a reference to be signed.
Reference^ reference = gcnew Reference;
reference->Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform^ env = gcnew 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 ) );
if ( (doc->FirstChild)->GetType() == XmlDeclaration::typeid )
{
doc->RemoveChild( doc->FirstChild );
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter^ xmltw = gcnew XmlTextWriter( SignedFileName,gcnew UTF8Encoding( false ) );
doc->WriteTo( xmltw );
xmltw->Close();
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
Boolean VerifyXmlFile( String^ Name, RSA^ Key )
{
// Create a new XML document.
XmlDocument^ xmlDocument = gcnew XmlDocument;
// Load the passed XML file into the document.
xmlDocument->Load( Name );
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml^ signedXml = gcnew SignedXml( xmlDocument );
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList^ nodeList = xmlDocument->GetElementsByTagName( "Signature" );
// Load the signature node.
signedXml->LoadXml( safe_cast<XmlElement^>(nodeList->Item( 0 )) );
// Check the signature and return the result.
return signedXml->CheckSignature( Key );
}
// Create example data to sign.
void CreateSomeXml( String^ FileName )
{
// Create a new XmlDocument Object*.
XmlDocument^ document = gcnew XmlDocument;
// Create a new XmlNode object.
XmlNode^ node = document->CreateNode( XmlNodeType::Element, "", "MyElement", "samples" );
// Add some text to the node.
node->InnerText = "Example text to be signed.";
// Append the node to the document.
document->AppendChild( node );
// Save the XML document to the file name specified.
XmlTextWriter^ xmltw = gcnew XmlTextWriter( FileName,gcnew UTF8Encoding( false ) );
document->WriteTo( xmltw );
xmltw->Close();
}
int main()
{
try
{
// Generate a signing key.
RSA^ Key = RSA::Create();
// Create an XML file to sign.
CreateSomeXml( "Example.xml" );
Console::WriteLine( "New XML file created." );
// Sign the XML that was just created and save it in a
// new file.
SignXmlFile( "Example.xml", "signedExample.xml", Key );
Console::WriteLine( "XML file signed." );
// Verify the signature of the signed XML.
Console::WriteLine( "Verifying signature..." );
bool result = VerifyXmlFile( "SignedExample.xml", Key );
// 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 ( CryptographicException^ e )
{
Console::WriteLine( e->Message );
}
}
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
try
{
// Generate a signing key.
RSA Key = RSA.Create();
// Create an XML file to sign.
CreateSomeXml("Example.xml");
Console.WriteLine("New XML file created.");
// Sign the XML that was just created and save it in a
// new file.
SignXmlFile("Example.xml", "signedExample.xml", Key);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml", Key);
// 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(CryptographicException e)
{
Console.WriteLine(e.Message);
}
}
// Sign an XML file and save the signature in a new file. This method does not
// save the public key within the XML file. This file cannot be verified unless
// the verifying code has the key with which it was signed.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key)
{
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Load the passed XML file using its name.
doc.Load(new XmlTextReader(FileName));
// 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));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static Boolean VerifyXmlFile(String Name, RSA Key)
{
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
// Create example data to sign.
public static void CreateSomeXml(string FileName)
{
// Create a new XmlDocument object.
XmlDocument document = new XmlDocument();
// Create a new XmlNode object.
XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples");
// Add some text to the node.
node.InnerText = "Example text to be signed.";
// Append the node to the document.
document.AppendChild(node);
// Save the XML document to the file name specified.
XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false));
document.WriteTo(xmltw);
xmltw.Close();
}
}
'
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Public Class SignVerifyEnvelope
Overloads Public Shared Sub Main(args() As [String])
Try
' Generate a signing key.
Dim Key As RSA = RSA.Create()
' Create an XML file to sign.
CreateSomeXml("Example.xml")
Console.WriteLine("New XML file created.")
' Sign the XML that was just created and save it in a
' new file.
SignXmlFile("Example.xml", "signedExample.xml", Key)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml", Key)
' 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 CryptographicException
Console.WriteLine(e.Message)
End Try
End Sub
' Sign an XML file and save the signature in a new file. This method does not
' save the public key within the XML file. This file cannot be verified unless
' the verifying code has the key with which it was signed.
Public Shared Sub SignXmlFile(FileName As String, SignedFileName As String, Key As RSA)
' Create a new XML document.
Dim doc As New XmlDocument()
' Load the passed XML file using its name.
doc.Load(New XmlTextReader(FileName))
' 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))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file against an asymmetric
' algorithm and return the result.
Public Shared Function VerifyXmlFile(Name As [String], Key As RSA) As [Boolean]
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature(Key)
End Function
' Create example data to sign.
Public Shared Sub CreateSomeXml(FileName As String)
' Create a new XmlDocument object.
Dim document As New XmlDocument()
' Create a new XmlNode object.
Dim node As XmlNode = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples")
' Add some text to the node.
node.InnerText = "Example text to be signed."
' Append the node to the document.
document.AppendChild(node)
' Save the XML document to the file name specified.
Dim xmltw As New XmlTextWriter(FileName, New UTF8Encoding(False))
document.WriteTo(xmltw)
xmltw.Close()
End Sub
End Class
次のコード例は、エンベロープ署名を使用して XML ドキュメントの 1 つの要素に署名して検証する方法を示しています。
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
#using <System.Xml.dll>
#using <System.Security.dll>
#using <System.dll>
using namespace System;
using namespace System::Security::Cryptography;
using namespace System::Security::Cryptography::Xml;
using namespace System::Text;
using namespace System::Xml;
// Sign an XML file and save the signature in a new file.
static void SignXmlFile( String^ FileName, String^ SignedFileName, RSA^ Key, array<String^>^ElementsToSign )
{
// Check the arguments.
if ( FileName == nullptr )
throw gcnew ArgumentNullException( L"FileName" );
if ( SignedFileName == nullptr )
throw gcnew ArgumentNullException( L"SignedFileName" );
if ( Key == nullptr )
throw gcnew ArgumentNullException( L"Key" );
if ( ElementsToSign == nullptr )
throw gcnew ArgumentNullException( L"ElementsToSign" );
// Create a new XML document.
XmlDocument^ doc = gcnew XmlDocument;
// Format the document to ignore white spaces.
doc->PreserveWhitespace = false;
// Load the passed XML file using it's name.
doc->Load( gcnew XmlTextReader( FileName ) );
// Create a SignedXml object.
SignedXml^ signedXml = gcnew SignedXml( doc );
// Add the key to the SignedXml document.
signedXml->SigningKey = Key;
// Loop through each passed element to sign
// and create a reference.
System::Collections::IEnumerator^ myEnum = ElementsToSign->GetEnumerator();
while ( myEnum->MoveNext() )
{
String^ s = safe_cast<String^>(myEnum->Current);
// Create a reference to be signed.
Reference^ reference = gcnew Reference;
reference->Uri = s;
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform^ env = gcnew XmlDsigEnvelopedSignatureTransform;
reference->AddTransform( env );
// Add the reference to the SignedXml object.
signedXml->AddReference( reference );
}
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo^ keyInfo = gcnew KeyInfo;
keyInfo->AddClause( gcnew RSAKeyValue( dynamic_cast<RSA^>(Key) ) );
signedXml->KeyInfo = keyInfo;
// 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 ) );
if ( dynamic_cast<XmlDeclaration^>(doc->FirstChild) )
{
doc->RemoveChild( doc->FirstChild );
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter^ xmltw = gcnew XmlTextWriter( SignedFileName,gcnew UTF8Encoding( false ) );
doc->WriteTo( xmltw );
xmltw->Close();
}
// Verify the signature of an XML file and return the result.
static Boolean VerifyXmlFile( String^ Name )
{
// Check the arguments.
if ( Name == nullptr )
throw gcnew ArgumentNullException( L"Name" );
// Create a new XML document.
XmlDocument^ xmlDocument = gcnew XmlDocument;
// Format using white spaces.
xmlDocument->PreserveWhitespace = true;
// Load the passed XML file into the document.
xmlDocument->Load( Name );
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml^ signedXml = gcnew SignedXml( xmlDocument );
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList^ nodeList = xmlDocument->GetElementsByTagName( L"Signature" );
// Load the signature node.
signedXml->LoadXml( dynamic_cast<XmlElement^>(nodeList->Item( 0 )) );
// Check the signature and return the result.
return signedXml->CheckSignature();
}
int main()
{
// Generate a signing key.
RSA^ Key = RSA::Create();
try
{
// Specify an element to sign.
array<String^>^elements = {L"#tag1"};
// Sign an XML file and save the signature to a
// new file.
SignXmlFile( L"Test.xml", L"SignedExample.xml", Key, elements );
Console::WriteLine( L"XML file signed." );
// Verify the signature of the signed XML.
Console::WriteLine( L"Verifying signature..." );
bool result = VerifyXmlFile( L"SignedExample.xml" );
// Display the results of the signature verification to
// the console.
if ( result )
{
Console::WriteLine( L"The XML signature is valid." );
}
else
{
Console::WriteLine( L"The XML signature is not valid." );
}
}
catch ( CryptographicException^ e )
{
Console::WriteLine( e->Message );
}
finally
{
// Clear resources associated with the
// RSA instance.
Key->Clear();
}
return 1;
}
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
// Generate a signing key.
RSA Key = RSA.Create();
try
{
// Specify an element to sign.
string[] elements = { "#tag1" };
// Sign an XML file and save the signature to a
// new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml");
// 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 (CryptographicException e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear resources associated with the
// RSA instance.
Key.Clear();
}
}
// Sign an XML file and save the signature in a new file.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign)
{
// Check the arguments.
if (FileName == null)
throw new ArgumentNullException("FileName");
if (SignedFileName == null)
throw new ArgumentNullException("SignedFileName");
if (Key == null)
throw new ArgumentNullException("Key");
if (ElementsToSign == null)
throw new ArgumentNullException("ElementsToSign");
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Format the document to ignore white spaces.
doc.PreserveWhitespace = false;
// Load the passed XML file using it's name.
doc.Load(new XmlTextReader(FileName));
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Loop through each passed element to sign
// and create a reference.
foreach (string s in ElementsToSign)
{
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = s;
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
}
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue((RSA)Key));
signedXml.KeyInfo = keyInfo;
// 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));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file and return the result.
public static Boolean VerifyXmlFile(String Name)
{
// Check the arguments.
if (Name == null)
throw new ArgumentNullException("Name");
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Format using white spaces.
xmlDocument.PreserveWhitespace = true;
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature();
}
}
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Module SignVerifyEnvelope
Sub Main(ByVal args() As String)
' Generate a signing key.
Dim Key As RSA = RSA.Create()
Try
' Specify an element to sign.
Dim elements As String() = New String() {"#tag1"}
' Sign an XML file and save the signature to a
' new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml")
' 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 CryptographicException
Console.WriteLine(e.Message)
Finally
' Clear resources associated with the
' RSA instance.
Key.Clear()
End Try
End Sub
' Sign an XML file and save the signature in a new file.
Sub SignXmlFile(ByVal FileName As String, ByVal SignedFileName As String, ByVal Key As RSA, ByVal ElementsToSign() As String)
' Check the arguments.
If FileName Is Nothing Then
Throw New ArgumentNullException("FileName")
End If
If SignedFileName Is Nothing Then
Throw New ArgumentNullException("SignedFileName")
End If
If Key Is Nothing Then
Throw New ArgumentNullException("Key")
End If
If ElementsToSign Is Nothing Then
Throw New ArgumentNullException("ElementsToSign")
End If
' Create a new XML document.
Dim doc As New XmlDocument()
' Format the document to ignore white spaces.
doc.PreserveWhitespace = False
' Load the passed XML file using it's name.
doc.Load(New XmlTextReader(FileName))
' Create a SignedXml object.
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
signedXml.SigningKey = Key
' Loop through each passed element to sign
' and create a reference.
Dim s As String
For Each s In ElementsToSign
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = s
' 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)
Next s
' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
Dim keyInfo As New KeyInfo()
keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
signedXml.KeyInfo = keyInfo
' 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))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file and return the result.
Function VerifyXmlFile(ByVal Name As String) As [Boolean]
' Check the arguments.
If Name Is Nothing Then
Throw New ArgumentNullException("Name")
End If
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Format using white spaces.
xmlDocument.PreserveWhitespace = True
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature()
End Function
End Module
注釈
クラスは SignedXml 、WORLD Wide Web Consortium (W3C) XML Signature Syntax and Processing Specification (XMLDSIG (XML Digital Signature) とも呼ばれます) の .NET 実装です。 XMLDSIG は、標準ベースの相互運用可能な方法であり、XML ドキュメントのすべてまたは一部、または URI (Uniform Resource Identifier) からアドレス指定可能なその他のデータに署名して検証します。
標準の方法で SignedXml アプリケーションまたは組織間で署名付き XML データを共有する必要がある場合は常に、 クラスを使用します。 このクラスを使用して署名されたデータは、XMLDSIG の W3C 仕様の準拠する実装によって検証できます。
SignedXmlクラスを使用すると、次の 3 種類の XML デジタル署名を作成できます。
[署名の種類] | [説明] |
---|---|
封筒付き署名 | 署名は、署名される XML 要素内に含まれています。 |
署名を包み込む | 署名された XML は、 要素内に <Signature> 含まれています。 |
内部デタッチされた署名 | 署名と署名付き XML は同じドキュメント内にありますが、どちらの要素にももう一方の要素は含まれていません。 |
また、外部デタッチされた署名と呼ばれる 4 番目の種類の署名もあります。これは、データと署名が別の XML ドキュメントにある場合です。 外部デタッチされたシグネチャは、 クラスでは SignedXml サポートされていません。
XML 署名の構造
XMLDSIG は、XML ドキュメントのデジタル署名、または URI からアドレス指定可能なその他のデータを含む要素を作成 <Signature>
します。 要素には <Signature>
、必要に応じて、署名を検証するキーを検索する場所と、署名に使用された暗号化アルゴリズムに関する情報を含めることができます。 基本構造は次のとおりです。
<Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Base64EncodedValue==</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>AnotherBase64EncodedValue===</SignatureValue>
</Signature>
この構造の主な部分は次のとおりです。
<CanonicalizationMethod>
要素署名検証のために XML/text からバイトに要素を
Signature
書き換える規則を指定します。 .NET の既定値は で、 http://www.w3.org/TR/2001/REC-xml-c14n-20010315信頼できるアルゴリズムを識別します。 この要素は、 プロパティによって SignedInfo.CanonicalizationMethod 表されます。<SignatureMethod>
要素の値
<SignatureValue>
を生成するために 要素に適用された、署名の<Signature>
生成と検証に使用されるアルゴリズムを指定します。 前の例では、値 http://www.w3.org/2000/09/xmldsig#rsa-sha1 によって RSA PKCS1 SHA-1 署名が識別されます。 SHA-1 との競合の問題により、Microsoftは SHA-256 以上に基づくセキュリティ モデルを推奨しています。 この要素は、 プロパティによって SignatureMethod 表されます。<SignatureValue>
要素要素の暗号化署名を
<Signature>
指定します。 この署名が検証されない場合、ブロックの<Signature>
一部が改ざんされ、ドキュメントは無効と見なされます。 値が<CanonicalizationMethod>
信頼できる限り、この値は改ざんに対して非常に耐性があります。 この要素は、 プロパティによって SignatureValue 表されます。URI
要素の<Reference>
属性URI 参照を使用してデータ オブジェクトを指定します。 この属性は、 プロパティによって Reference.Uri 表されます。
属性を
URI
指定しない、つまり プロパティを Reference.Uri にnull
設定することは、受信側のアプリケーションがオブジェクトの ID を認識することが期待されることを意味します。 ほとんどの場合、null
URI によって例外がスローされます。 アプリケーションが必要なnull
プロトコルと相互運用している場合を除き、URI を使用しないでください。属性を
URI
空の文字列に設定すると、ドキュメントのルート要素が署名されていることを示します。これは、エンベロープ署名の形式です。属性の
URI
値が #で始まる場合、値は現在のドキュメントの要素に解決される必要があります。 このフォームは、サポートされている署名の種類 (エンベロープ署名、エンベロープ署名、または内部デタッチされた署名) で使用できます。それ以外の場合は、外部リソースのデタッチされたシグネチャと見なされ、 クラスでは SignedXml サポートされていません。
<Transforms>
要素署名者がダイジェストされたデータ オブジェクトを取得する方法を説明する要素の順序付きリスト
<Transform>
が含まれます。 変換アルゴリズムは正規化メソッドに似ていますが、要素を<Signature>
書き換える代わりに、 要素の 属性によって識別されるコンテンツをURI
<Reference>
書き換えます。<Transforms>
要素は、TransformChain クラスで表されます。各変換アルゴリズムは、XML (XPath ノード セット) またはバイトを入力として受け取るように定義されます。 現在のデータの形式が変換入力要件と異なる場合は、変換ルールが適用されます。
各変換アルゴリズムは、XML またはバイトを出力として生成するものとして定義されます。
最後の変換アルゴリズムの出力がバイト単位で定義されていない (または変換が指定されていない) 場合、 正規化メソッド は暗黙的な変換として使用されます (要素で別の
<CanonicalizationMethod>
アルゴリズムが指定された場合でも)。変換アルゴリズムの の値 http://www.w3.org/2000/09/xmldsig#enveloped-signature は、ドキュメントから 要素を削除
<Signature>
すると解釈されるルールをエンコードします。 それ以外の場合、封筒署名の検証者は署名を含めてドキュメントをダイジェストしますが、署名者は署名が適用される前にドキュメントをダイジェストし、異なる回答が得られます。
<DigestMethod>
要素要素の 属性によって識別される変換されたコンテンツに適用するダイジェスト (暗号化ハッシュ) メソッドを
URI
<Reference>
識別します。 これは、 プロパティによって Reference.DigestMethod 表されます。
正規化方法の選択
別の値を使用する必要がある仕様と相互運用しない限り、既定の .NET 正規化メソッド (値が である XML-C14N 1.0 アルゴリズム) http://www.w3.org/TR/2001/REC-xml-c14n-20010315を使用することをお勧めします。 XML-C14N 1.0 アルゴリズムは、特に適用する暗黙的な最終変換であるため、XMLDSIG のすべての実装でサポートされている必要があります。
コメントの保持をサポートする正規化アルゴリズムのバージョンがあります。 コメントを保持する正規化メソッドは、"表示される記号" の原則に違反しているため、推奨されません。 つまり、要素内の <Signature>
コメントでは、シグネチャの実行方法に関する処理ロジックは変更されず、シグネチャ値が何であるかだけが変更されます。 弱い署名アルゴリズムと組み合わせると、コメントを含めることにより、攻撃者はハッシュ競合を強制する不要な自由を与え、改ざんされたドキュメントが正当に見えるようにします。 .NET Frameworkでは、組み込みの正規化器のみが既定でサポートされています。 追加またはカスタムの正規化をサポートするには、 プロパティを SafeCanonicalizationMethods 参照してください。 ドキュメントで、 プロパティで表される SafeCanonicalizationMethods コレクションにない正規化メソッドを使用する場合、 CheckSignature メソッドは を返 false
します。
Note
非常に防御的なアプリケーションでは、署名者がコレクションから使用するとは思わない値を SafeCanonicalizationMethods 削除できます。
参照値は改ざんから保護されていますか?
はい。値は <Reference>
改ざんから安全です。 .NET は、 <SignatureValue>
値とそれに関連付けられた変換を処理する <Reference>
前に計算を検証し、悪意のある処理命令を回避するために早期に中止します。
署名する要素の選択
可能であれば、属性に "" の値を URI
使用することをお勧めします (または、プロパティを Uri 空の文字列に設定します)。 つまり、ドキュメント全体がダイジェスト計算と見なされます。つまり、ドキュメント全体が改ざんから保護されます。
ID 属性が "foo" である要素を参照して、#fooなどのアンカーの形式で値を確認 URI
することは非常に一般的です。 残念ながら、コンテキストではなくターゲット要素のコンテンツのみが含まれるので、これを改ざんするのは簡単です。 この区別を悪用することは、XML 署名ラップ (XSW) と呼ばれます。
アプリケーションでコメントがセマンティックであると見なされる場合 (XML を扱う場合は一般的ではありません)、"#foo" ではなく "#xpointer(/)" を使用し、"#xpointer(id('foo'))" を使用する必要があります。 #xpointerバージョンはコメントを含んでいると解釈されますが、shortname フォームはコメントを除外しています。
部分的に保護されたドキュメントのみを受け入れる必要があり、署名が保護されているのと同じコンテンツを確実に読み取る必要がある場合は、 メソッドを使用します GetIdElement 。
KeyInfo 要素に関するセキュリティに関する考慮事項
省略可能な <KeyInfo>
要素 (つまり、シグネチャを検証するためのキーを KeyInfo 含む プロパティ) のデータは信頼できません。
特に、値が KeyInfo ベア RSA、DSA、または ECDSA 公開キーを表している場合、署名が有効であることを報告するメソッドにもかかわらず CheckSignature 、ドキュメントが改ざんされている可能性があります。 これは、改ざんを行うエンティティが新しいキーを生成し、改ざんされたドキュメントにその新しいキーで再署名する必要があるために発生する可能性があります。 そのため、アプリケーションで公開キーが期待される値であることを確認しない限り、ドキュメントは改ざんされたかのように扱う必要があります。 そのためには、アプリケーションがドキュメント内に埋め込まれている公開キーを調べて、ドキュメント コンテキストの既知の値の一覧に対して検証する必要があります。 たとえば、ドキュメントが既知のユーザーによって発行されたと認識できる場合は、そのユーザーが使用する既知のキーの一覧に対してキーを確認します。
また、 メソッドを使用する代わりに、 メソッドを使用 CheckSignatureReturningKey して、ドキュメントの処理後にキーを CheckSignature 確認することもできます。 ただし、最適なセキュリティを確保するには、事前にキーを確認する必要があります。
または、要素の内容を読み取るのではなく、ユーザーの登録済み公開キーを <KeyInfo>
試してみることを検討してください。
X509Data 要素に関するセキュリティに関する考慮事項
省略可能な <X509Data>
要素は 要素の <KeyInfo>
子であり、X509 証明書または X509 証明書の識別子を 1 つ以上含みます。 要素内の <X509Data>
データも、本質的に信頼されるべきではありません。
埋め込み <X509Data>
要素を使用してドキュメントを検証する場合、.NET では、公開キーを使用してドキュメント署名を検証できる X509 証明書にデータが解決されることのみが検証されます。 パラメーターを CheckSignature にfalse
設定して メソッドをverifySignatureOnly
呼び出すのとは異なり、失効チェックは実行されません。チェーン信頼はチェックされません。また、有効期限も検証されません。 アプリケーションが証明書自体を抽出し、 パラメーターを にCheckSignaturefalse
設定してメソッドverifySignatureOnly
に渡しても、ドキュメントの改ざんを防ぐには十分な検証ではありません。 証明書は、署名されているドキュメントに適していると確認する必要があります。
埋め込み署名証明書を使用すると、セクションでもドキュメント コンテンツでも <X509Data>
、便利なキーローテーション戦略を提供できます。 この方法を使用する場合、アプリケーションは証明書を手動で抽出し、次のような検証を実行する必要があります。
証明書は、公開証明書がアプリケーションに埋め込まれている証明機関 (CA) によって直接、またはチェーン経由で発行されました。
既知のサブジェクト名などの追加のチェックなしで OS 提供の信頼リストを使用するだけでは、 の SignedXml改ざんを防ぐには十分ではありません。
証明書は、ドキュメント署名時に有効期限が切れていない (ほぼリアルタイムのドキュメント処理の場合は "now" であることが確認されます)。
失効をサポートする CA によって発行された有効期間の長い証明書の場合は、証明書が取り消されていないことを確認します。
証明書のサブジェクトは、現在のドキュメントに適していると検証されます。
変換アルゴリズムの選択
特定の値 (XrML など) を指定した仕様と相互運用する場合は、その仕様に従う必要があります。 封筒署名がある場合 (ドキュメント全体に署名する場合など)、(クラスで表される) を使用 http://www.w3.org/2000/09/xmldsig#enveloped-signature する XmlDsigEnvelopedSignatureTransform 必要があります。 暗黙的な XML-C14N 変換も指定できますが、必須ではありません。 エンベロープ署名またはデタッチされたシグネチャの場合、変換は必要ありません。 暗黙的な XML-C14N 変換は、すべてを処理します。
Microsoft セキュリティ情報 MS16-035 によって導入されたセキュリティにより、.NET ではドキュメント検証で使用できる変換が既定で制限されており、信頼されていない変換CheckSignatureによって常に が返false
されます。 特に、追加の入力を必要とする変換 (XML 内の子要素として指定) は、悪意のあるユーザーによる不正使用の影響を受けないため、許可されなくなりました。 W3C では、これらの制限の影響を受ける 2 つの主な変換である XPath 変換と XSLT 変換を回避することをお勧めします。
外部参照に関する問題
アプリケーションが現在のコンテキストに適していると思われる外部参照を検証しない場合、多くのセキュリティ脆弱性 (サービス拒否、分散型リフレクション拒否、情報漏えい、署名バイパス、リモート コード実行など) を提供する方法で悪用される可能性があります。 アプリケーションが外部参照 URI を検証した場合でも、リソースが 2 回読み込まれるという問題が残ります。アプリケーションが読み取るときは 1 回、読み取り時 SignedXml は 1 回です。 アプリケーションの読み取りとドキュメントの検証の手順が同じコンテンツを持っていることは保証されないため、署名は信頼性を提供しません。
外部参照のリスクが考えられると、 SignedXml 外部参照が検出されると例外がスローされます。 この問題の詳細については、 KB 記事の3148821を参照してください。
コンストラクター
SignedXml() |
SignedXml クラスの新しいインスタンスを初期化します。 |
SignedXml(XmlDocument) |
指定した XML ドキュメントから SignedXml クラスの新しいインスタンスを初期化します。 |
SignedXml(XmlElement) |
指定した SignedXml オブジェクトから XmlElement クラスの新しいインスタンスを初期化します。 |
フィールド
m_signature | |
m_strSigningKeyName |
SignedXml オブジェクトに署名するための、インストールされているキーの名前を表します。 |
XmlDecryptionTransformUrl |
XML モード復号化変換の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigBase64TransformUrl |
base 64 変換の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigC14NTransformUrl |
Canonical XML 変換の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigC14NWithCommentsTransformUrl |
Canonical XML 変換の URI (Uniform Resource Identifier) をコメント付きで表します。 このフィールドは定数です。 |
XmlDsigCanonicalizationUrl |
XML デジタル署名のための標準の標準化アルゴリズムの URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigCanonicalizationWithCommentsUrl |
XML デジタル署名のための標準の標準化アルゴリズムの URI (Uniform Resource Identifier) を表し、コメントを格納します。 このフィールドは定数です。 |
XmlDsigDSAUrl |
XML デジタル署名のための標準の DSA アルゴリズムの URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigEnvelopedSignatureTransformUrl |
エンベロープ シグネチャ変換の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigExcC14NTransformUrl |
排他的 XML 標準化の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigExcC14NWithCommentsTransformUrl |
排他的 XML 標準化の URI (Uniform Resource Identifier) をコメント付きで表します。 このフィールドは定数です。 |
XmlDsigHMACSHA1Url |
XML デジタル署名のための標準の HMACSHA1 アルゴリズムの URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigMinimalCanonicalizationUrl |
XML デジタル署名のための標準の最小標準化アルゴリズムの URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigNamespaceUrl |
XML デジタル署名のための標準名前空間の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigRSASHA1Url |
XML デジタル署名のための標準の RSA 署名メソッドの URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigRSASHA256Url |
XML デジタル署名の SHA-256 署名メソッドバリエーションの RSA URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigRSASHA384Url |
XML デジタル署名の SHA-384 署名メソッドバリエーションの RSA URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigRSASHA512Url |
XML デジタル署名の SHA-512 署名メソッドバリエーションの RSA URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigSHA1Url |
XML デジタル署名のスタンダード SHA1 ダイジェスト メソッドの Uniform Resource Identifier (URI) を表します。 このフィールドは定数です。 |
XmlDsigSHA256Url |
XML デジタル署名のスタンダード SHA256 ダイジェスト メソッドの Uniform Resource Identifier (URI) を表します。 このフィールドは定数です。 |
XmlDsigSHA384Url |
XML デジタル署名のスタンダード SHA384 ダイジェスト メソッドの Uniform Resource Identifier (URI) を表します。 このフィールドは定数です。 |
XmlDsigSHA512Url |
XML デジタル署名のスタンダード SHA512 ダイジェスト メソッドの Uniform Resource Identifier (URI) を表します。 このフィールドは定数です。 |
XmlDsigXPathTransformUrl |
XML Path Language (XPath) の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlDsigXsltTransformUrl |
XSLT 変換の URI (Uniform Resource Identifier) を表します。 このフィールドは定数です。 |
XmlLicenseTransformUrl |
署名の XrML ライセンスを正規化するために使用されるライセンス変換アルゴリズムの URI (Uniform Resource Identifier) を表します。 |
プロパティ
EncryptedXml |
XML 暗号化処理規則を定義する EncryptedXml オブジェクトを取得または設定します。 |
KeyInfo | |
Resolver |
現在の XmlResolver オブジェクトを設定します。 |
SafeCanonicalizationMethods |
正規化アルゴリズムが明示的に許可されているメソッドの名前を取得します。 |
Signature | |
SignatureFormatValidator |
XML 署名の (暗号によるセキュリティではなく) 書式を検証するために呼び出されるデリゲートを取得します。 |
SignatureLength |
現在の SignedXml オブジェクトの署名の長さを取得します。 |
SignatureMethod |
現在の SignedXml オブジェクトの署名メソッドを取得します。 |
SignatureValue |
現在の SignedXml オブジェクトの署名値を取得します。 |
SignedInfo |
現在の SignedInfo オブジェクトの SignedXml オブジェクトを取得します。 |
SigningKey |
SignedXml オブジェクトに署名するために使用する非対称アルゴリズム キーを取得または設定します。 |
SigningKeyName |
SignedXml オブジェクトに署名するための、インストールされているキーの名前を取得または設定します。 |
メソッド
AddObject(DataObject) |
署名されるオブジェクトのリストに DataObject オブジェクトを追加します。 |
AddReference(Reference) |
Reference オブジェクトを、XML デジタル署名の作成に使用するダイジェスト メソッド、ダイジェスト値、および変換を記述する SignedXml オブジェクトに追加します。 |
CheckSignature() |
Signature プロパティが署名内の公開キーを使用して検証するかどうかを判断します。 |
CheckSignature(AsymmetricAlgorithm) |
Signature プロパティが指定したキーに対して検証するかどうかを判断します。 |
CheckSignature(KeyedHashAlgorithm) |
Signature プロパティが指定のメッセージ認証コード (MAC: message authentication code) アルゴリズムに対して検証するかどうかを判断します。 |
CheckSignature(X509Certificate2, Boolean) |
Signature プロパティが指定した X509Certificate2 オブジェクトに対して検証するかどうか、およびオプションで証明書が有効かどうかを判断します。 |
CheckSignatureReturningKey(AsymmetricAlgorithm) |
Signature プロパティが署名内の公開キーを使用して検証するかどうかを判断します。 |
ComputeSignature() |
XML デジタル署名を計算します。 |
ComputeSignature(KeyedHashAlgorithm) |
指定したメッセージ認証コード (MAC: message authentication code) アルゴリズムを使用して XML デジタル署名を計算します。 |
Equals(Object) |
指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。 (継承元 Object) |
GetHashCode() |
既定のハッシュ関数として機能します。 (継承元 Object) |
GetIdElement(XmlDocument, String) |
指定した XmlElement オブジェクトから、指定した ID の XmlDocument オブジェクトを返します。 |
GetPublicKey() |
署名の公開キーを返します。 |
GetType() |
現在のインスタンスの Type を取得します。 (継承元 Object) |
GetXml() |
SignedXml オブジェクトの XML 表現を返します。 |
LoadXml(XmlElement) |
XML 要素から SignedXml の状態を読み込みます。 |
MemberwiseClone() |
現在の Object の簡易コピーを作成します。 (継承元 Object) |
ToString() |
現在のオブジェクトを表す文字列を返します。 (継承元 Object) |