HOW TO:驗證 XML 文件的數位簽章
您可以使用 System.Security.Cryptography.Xml 命名空間中的類別,驗證以數位簽章簽署的 XML 資料。 XML 數位簽章 (XMLDSIG) 可讓您確保資料在簽署之後並未遭到修改。 如需 XMLDSIG 標準的詳細資訊,請參閱全球資訊網協會 (W3C) 的規格,網址為 http://www.w3.org/TR/xmldsig-core/。
這個程序中的程式碼範例會示範如何驗證 <Signature> 項目所包含的 XML 數位簽章。 此範例會從金鑰容器中擷取 RSA 公開金鑰 (Public Key),再使用這個金鑰驗證簽章。
如需有關如何建立可以利用此技巧加以驗證之數位簽章的詳細資訊,請參閱 HOW TO:使用數位簽章簽署 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 類別的建構函式 (Constructor) 時,金鑰便會依名稱自動從金鑰容器載入。
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
從磁碟載入 XML 檔案,建立 XmlDocument 物件。 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);
找出 <signature> 項目,並建立新的 XmlNodeList 物件。
Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
將第一個 <signature> 項目的 XML 載入至 SignedXml 物件。
signedXml.LoadXml(CType(nodeList(0), XmlElement))
signedXml.LoadXml((XmlElement)nodeList[0]);
使用 CheckSignature 方法和 RSA 公開金鑰檢查簽章。 這個方法會傳回指示成功或失敗的布林 (Boolean) 值。
Return signedXml.CheckSignature(Key)
return signedXml.CheckSignature(Key);
範例
Imports System
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml
Module VerifyXML
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")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXml(xmlDoc, rsaKey)
' 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 Exception
Console.WriteLine(e.Message)
End Try
End Sub
' Verify the signature of an XML file against an asymmetric
' algorithm and return the result.
Function VerifyXml(ByVal Doc As XmlDocument, ByVal Key As RSA) As [Boolean]
' 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 new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(Doc)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
' Throw an exception if no signature was found.
If nodeList.Count <= 0 Then
Throw New CryptographicException("Verification failed: No Signature was found in the document.")
End If
' This example only supports one signature for
' the entire XML document. Throw an exception
' if more than one signature was found.
If nodeList.Count >= 2 Then
Throw New CryptographicException("Verification failed: More that one signature was found for the document.")
End If
' Load the first <signature> node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature(Key)
End Function
End Module
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
public class VerifyXML
{
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");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXml(xmlDoc, rsaKey);
// 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 (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count >= 2)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
}
這個範例假設,在已編譯程式的相同目錄中,有名為 "test.xml" 的檔案。 "test.xml" 檔案必須使用 HOW TO:使用數位簽章簽署 XML 文件 中所描述的技巧加以簽署。
編譯程式碼
若要編譯這個範例,您需要包含對 System.Security.dll 的參考。
包含下列命名空間:System.Xml、System.Security.Cryptography 和 System.Security.Cryptography.Xml。
安全性
請勿以純文字格式儲存或傳輸非對稱金鑰組的私密金鑰。 如需對稱和非對稱密碼編譯金鑰的詳細資訊,請參閱產生加密和解密金鑰。
請勿直接將私密金鑰嵌入原始程式碼內。 使用 Ildasm.exe (MSIL 反組譯工具) 或在文字編輯器 (例如記事本) 中開啟組件,可以輕易從組件讀取內嵌金鑰。
請參閱
工作
參考
System.Security.Cryptography.Xml