HOW TO:使用 X.509 憑證加密 XML 項目
更新:2007 年 11 月
您可以使用 System.Security.Cryptography.Xml 命名空間中的類別,加密 XML 文件中的項目。XML 加密是交換或儲存加密 XML 資料的標準方法,無資料遭竊取之虞。如需 XML 加密標準的詳細資訊,請參閱全球資訊網協會 (W3C) 的 XML 加密規格,網址為 http://www.w3.org/TR/xmldsig-core/。
您可以使用 XML 加密,以內含加密 XML 資料的 <EncryptedData> 項目取代任何 XML 項目或文件。<EncryptedData> 項目可以包含子項目,而子項目會包含有關加密時所使用之金鑰和程序的資訊。XML 加密讓文件可以包含多個加密項目,並且也允許一個項目被加密數次。這個程序中的程式碼範例會說明如何建立 <EncryptedData> 項目和數個其他子項目,以便稍後在解密時使用。
這個範例使用兩個金鑰加密 XML 項目。它會使用憑證建立工具 (Makecert.exe) 產生測試用的 X.509 憑證,並將此憑證儲存到憑證存放區。接著,此範例會以程式設計方式擷取憑證,使用此憑證來加密以 Encrypt 方法加密的 XML 項目。也就是說,Encrypt 方法會建立另一個工作階段金鑰,再用它來加密 XML 文件。這個方法會加密工作階段金鑰,並將它與加密的 XML 一併儲存在新的 <EncryptedData> 項目中。
若要解密 XML 項目,只要呼叫 DecryptDocument 方法,此方法會自動從存放區擷取 X.509 憑證,並執行必要的解密作業。如需有關如何解密以此程序加密之 XML 項目的詳細資訊,請參閱 HOW TO:使用 X.509 憑證解密 XML 項目。
當多個應用程式需要共用加密資料,或應用程式在執行時間之間需要儲存加密資料的情況下,適用這個範例。
若要使用 X.509 憑證加密 XML 項目
使用憑證建立工具 (Makecert.exe) 產生測試用的 X.509 憑證,並將它置於本機使用者存放區。您必須產生交換金鑰,並將它設成可以匯出。執行下列命令:
makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my
建立 X509Store 物件並將它初始化,以開啟目前的使用者存放區。
Dim store As New X509Store(StoreLocation.CurrentUser)
X509Store store = new X509Store(StoreLocation.CurrentUser);
以唯讀模式開啟存放區。
store.Open(OpenFlags.ReadOnly)
store.Open(OpenFlags.ReadOnly);
使用存放區內的所有憑證初始化 X509Certificate2Collection。
Dim certCollection As X509Certificate2Collection = store.Certificates
X509Certificate2Collection certCollection = store.Certificates;
列舉存放區中的憑證,找出具有適當名稱的憑證。在這個範例中,憑證的名稱為 "CN=XML_ENC_TEST_CERT"。
Dim cert As X509Certificate2 = Nothing ' Loop through each certificate and find the certificate ' with the appropriate name. Dim c As X509Certificate2 For Each c In certCollection If c.Subject = "CN=XML_ENC_TEST_CERT" Then cert = c Exit For End If Next c
X509Certificate2 cert = null; // Loop through each certificate and find the certificate // with the appropriate name. foreach (X509Certificate2 c in certCollection) { if (c.Subject == "CN=XML_ENC_TEST_CERT") { cert = c; break; } }
找到憑證之後,請關閉存放區。
store.Close()
store.Close();
從磁碟載入 XML 檔案,建立 XmlDocument 物件。XmlDocument 物件包含要加密的 XML 項目。
Dim xmlDoc As New XmlDocument()
XmlDocument xmlDoc = new XmlDocument();
在 XmlDocument 物件中尋找指定的項目,並建立新的 XmlElement 物件以表示您要加密的項目。在這個範例中,"creditcard" 項目已加密。
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
建立 EncryptedXml 類別的新執行個體,並利用該執行個體使用 X.509 憑證來加密指定的項目。Encrypt 方法會傳回加密的項目做為 EncryptedData 物件。
Dim eXml As New EncryptedXml() ' Encrypt the element. Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
EncryptedXml eXml = new EncryptedXml(); // Encrypt the element. EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
將項目從原始的 XmlDocument 物件取代為 EncryptedData 項目。
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
儲存 XmlDocument 物件。
xmlDoc.Save("test.xml")
xmlDoc.Save("test.xml");
範例
Imports System
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates
Module Program
Sub Main(ByVal args() As String)
Try
' Create an XmlDocument object.
Dim xmlDoc As New XmlDocument()
' Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = True
xmlDoc.Load("test.xml")
' Open the X.509 "Current User" store in read only mode.
Dim store As New X509Store(StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly)
' Place all certificates in an X509Certificate2Collection object.
Dim certCollection As X509Certificate2Collection = store.Certificates
Dim cert As X509Certificate2 = Nothing
' Loop through each certificate and find the certificate
' with the appropriate name.
Dim c As X509Certificate2
For Each c In certCollection
If c.Subject = "CN=XML_ENC_TEST_CERT" Then
cert = c
Exit For
End If
Next c
If cert Is Nothing Then
Throw New CryptographicException("The X.509 certificate could not be found.")
End If
' Close the store.
store.Close()
' Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", cert)
' Save the XML document.
xmlDoc.Save("test.xml")
' Display the encrypted XML to the console.
Console.WriteLine("Encrypted XML:")
Console.WriteLine()
Console.WriteLine(xmlDoc.OuterXml)
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub 'Main
Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
' Check the arguments.
If Doc Is Nothing Then
Throw New ArgumentNullException("Doc")
End If
If ElementToEncryptName Is Nothing Then
Throw New ArgumentNullException("ElementToEncrypt")
End If
If Cert Is Nothing Then
Throw New ArgumentNullException("Cert")
End If
''''''''''''''''''''''''''''''''''''''''''''''''
' Find the specified element in the XmlDocument
' object and create a new XmlElemnt object.
''''''''''''''''''''''''''''''''''''''''''''''''
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
' Throw an XmlException if the element was not found.
If elementToEncrypt Is Nothing Then
Throw New XmlException("The specified element was not found")
End If
''''''''''''''''''''''''''''''''''''''''''''''''
' Create a new instance of the EncryptedXml class
' and use it to encrypt the XmlElement with the
' X.509 Certificate.
''''''''''''''''''''''''''''''''''''''''''''''''
Dim eXml As New EncryptedXml()
' Encrypt the element.
Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
''''''''''''''''''''''''''''''''''''''''''''''''
' Replace the element from the original XmlDocument
' object with the EncryptedData element.
''''''''''''''''''''''''''''''''''''''''''''''''
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
End Sub
End Module
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;
class Program
{
static void Main(string[] args)
{
try
{
// Create an XmlDocument object.
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("test.xml");
// Open the X.509 "Current User" store in read only mode.
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
// Place all certificates in an X509Certificate2Collection object.
X509Certificate2Collection certCollection = store.Certificates;
X509Certificate2 cert = null;
// Loop through each certificate and find the certificate
// with the appropriate name.
foreach (X509Certificate2 c in certCollection)
{
if (c.Subject == "CN=XML_ENC_TEST_CERT")
{
cert = c;
break;
}
}
if (cert == null)
{
throw new CryptographicException("The X.509 certificate could not be found.");
}
// Close the store.
store.Close();
// Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", cert);
// Save the XML document.
xmlDoc.Save("test.xml");
// Display the encrypted XML to the console.
Console.WriteLine("Encrypted XML:");
Console.WriteLine();
Console.WriteLine(xmlDoc.OuterXml);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, X509Certificate2 Cert)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (ElementToEncrypt == null)
throw new ArgumentNullException("ElementToEncrypt");
if (Cert == null)
throw new ArgumentNullException("Cert");
////////////////////////////////////////////////
// Find the specified element in the XmlDocument
// object and create a new XmlElemnt object.
////////////////////////////////////////////////
XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
// Throw an XmlException if the element was not found.
if (elementToEncrypt == null)
{
throw new XmlException("The specified element was not found");
}
//////////////////////////////////////////////////
// Create a new instance of the EncryptedXml class
// and use it to encrypt the XmlElement with the
// X.509 Certificate.
//////////////////////////////////////////////////
EncryptedXml eXml = new EncryptedXml();
// Encrypt the element.
EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
////////////////////////////////////////////////////
// Replace the element from the original XmlDocument
// object with the EncryptedData element.
////////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}
}
這個範例假設,在已編譯程式的相同目錄中,有名為 "test.xml" 的檔案。它也會假設,"test.xml" 包含 "creditcard" 項目。您可以將下列 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。
安全性
這個範例所使用的 X.509 憑證僅供測試之用。應用程式必須使用由受信任的憑證授權單位產生的 X.509 憑證,或使用由 Microsoft Windows Certificate Server 產生的憑證。
請參閱
工作
參考
System.Security.Cryptography.Xml