您可以使用 System.Security.Cryptography.Xml 命名空間中的類別來加密 XML 文件內的項目。 XML 加密可讓您儲存或傳輸機密的 XML,而不必擔心資料被輕易讀取。 這個程序會使用進階加密標準 (AES) 演算法,來加密 XML 元素。
如需如何將使用這個程序加密的 XML 項目解密的相關資訊,請參閱 HOW TO:使用對稱金鑰解密 XML 項目。
當您使用如 AES 的對稱演算法來加密 XML 資料時,您必須使用相同的金鑰來加密和解密 XML 資料。 此程序中的範例假設將使用相同的金鑰來解密已加密的 XML,並且加密和解密的雙方同意使用的演算法和金鑰。 此範例不會儲存或加密在已加密 XML 中的 AES 金鑰。
這個範例適合單一應用程式需要根據記憶體中儲存的工作階段金鑰,或是根據衍生自密碼的強式密碼編譯金鑰,來加密資料。 對於兩個或多個應用程式需要共用加密的 XML 資料的情況,請考慮使用根據非對稱式演算法或 X.509 憑證的加密配置。
使用對稱金鑰加密 XML 項目
使用 Aes 類別產生對稱金鑰。 此金鑰會用來加密 XML 項目。
Aes? key = null; try { // Create a new AES key. key = Aes.Create();
Dim key As Aes = Nothing Try ' Create a new Aes key. key = Aes.Create()
藉由從磁碟載入 XML 檔案,建立 XmlDocument 物件。 XmlDocument 物件會包含要加密的 XML 項目。
// Load an XML document. XmlDocument xmlDoc = new() { PreserveWhitespace = true }; xmlDoc.Load("test.xml");
' Load an XML document. Dim xmlDoc As New XmlDocument() xmlDoc.PreserveWhitespace = True xmlDoc.Load("test.xml")
在 XmlDocument 物件中尋找指定的項目,並建立新的 XmlElement 物件以代表您想要加密的項目。 在此範例中,
"creditcard"
元素已加密。XmlElement? elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(0)
建立 EncryptedXml 類別的新執行個體,並使用它來利用對稱金鑰加密 XmlElement。 EncryptData 方法會以加密位元組陣列傳回已加密的項目。
EncryptedXml eXml = new(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
Dim eXml As New EncryptedXml() Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
建構 EncryptedData 物件並填入 XML 加密項目的 URL 識別項。 這個 URL 識別項可讓解密的一方知道 XML 包含加密的項目。 您可以使用 XmlEncElementUrl 欄位來指定 URL 識別項。
EncryptedData edElement = new() { Type = EncryptedXml.XmlEncElementUrl };
Dim edElement As New EncryptedData() edElement.Type = EncryptedXml.XmlEncElementUrl
建立 EncryptionMethod 物件,它會初始化為用來產生金鑰之密碼編譯演算法的 URL 識別項。 將 EncryptionMethod 物件傳遞至 EncryptionMethod 屬性。
string? encryptionMethod; if (Key is Aes) { encryptionMethod = EncryptedXml.XmlEncAES256Url; } else { // Throw an exception if the transform is not AES throw new CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
Dim encryptionMethod As String = Nothing If TypeOf Key Is Aes Then encryptionMethod = EncryptedXml.XmlEncAES256Url Else ' Throw an exception if the transform is not in the previous categories Throw New CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.") End If edElement.EncryptionMethod = New EncryptionMethod(encryptionMethod)
將加密項目資料加入 EncryptedData 物件。
edElement.CipherData.CipherValue = encryptedElement;
edElement.CipherData.CipherValue = encryptedElement
將來自原始 XmlDocument 物件的項目取代為 EncryptedData 項目。
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
範例
<root>
<creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</creditcard>
</root>
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
namespace CSCrypto
{
class Program
{
static void Main(string[] args)
{
Aes? key = null;
try
{
// Create a new AES key.
key = Aes.Create();
// Load an XML document.
XmlDocument xmlDoc = new()
{
PreserveWhitespace = true
};
xmlDoc.Load("test.xml");
// Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", key);
Console.WriteLine("The element was encrypted");
Console.WriteLine(xmlDoc.InnerXml);
Decrypt(xmlDoc, key);
Console.WriteLine("The element was decrypted");
Console.WriteLine(xmlDoc.InnerXml);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
key?.Clear();
}
}
public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
{
// Check the arguments.
ArgumentNullException.ThrowIfNull(Doc);
ArgumentNullException.ThrowIfNull(ElementName);
ArgumentNullException.ThrowIfNull(Key);
////////////////////////////////////////////////
// Find the specified element in the XmlDocument
// object and create a new XmlElement object.
////////////////////////////////////////////////
XmlElement? elementToEncrypt = Doc.GetElementsByTagName(ElementName)[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
// symmetric key.
//////////////////////////////////////////////////
EncryptedXml eXml = new();
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
////////////////////////////////////////////////
// Construct an EncryptedData object and populate
// it with the desired encryption information.
////////////////////////////////////////////////
EncryptedData edElement = new()
{
Type = EncryptedXml.XmlEncElementUrl
};
// Create an EncryptionMethod element so that the
// receiver knows which algorithm to use for decryption.
// Determine what kind of algorithm is being used and
// supply the appropriate URL to the EncryptionMethod element.
string? encryptionMethod;
if (Key is Aes)
{
encryptionMethod = EncryptedXml.XmlEncAES256Url;
}
else
{
// Throw an exception if the transform is not AES
throw new CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.");
}
edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
// Add the encrypted element data to the
// EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement;
////////////////////////////////////////////////////
// Replace the element from the original XmlDocument
// object with the EncryptedData element.
////////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}
public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
{
// Check the arguments.
ArgumentNullException.ThrowIfNull(Doc);
ArgumentNullException.ThrowIfNull(Alg);
// Find the EncryptedData element in the XmlDocument.
XmlElement? encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
// If the EncryptedData element was not found, throw an exception.
if (encryptedElement == null)
{
throw new XmlException("The EncryptedData element was not found.");
}
// Create an EncryptedData object and populate it.
EncryptedData edElement = new();
edElement.LoadXml(encryptedElement);
// Create a new EncryptedXml object.
EncryptedXml exml = new();
// Decrypt the element using the symmetric key.
byte[] rgbOutput = exml.DecryptData(edElement, Alg);
// Replace the encryptedData element with the plaintext XML element.
exml.ReplaceData(encryptedElement, rgbOutput);
}
}
}
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Module Program
Sub Main(ByVal args() As String)
Dim key As Aes = Nothing
Try
' Create a new Aes key.
key = Aes.Create()
' Load an XML document.
Dim xmlDoc As New XmlDocument()
xmlDoc.PreserveWhitespace = True
xmlDoc.Load("test.xml")
' Encrypt the "creditcard" element.
Encrypt(xmlDoc, "creditcard", key)
Console.WriteLine("The element was encrypted")
Console.WriteLine(xmlDoc.InnerXml)
Decrypt(xmlDoc, key)
Console.WriteLine("The element was decrypted")
Console.WriteLine(xmlDoc.InnerXml)
Catch e As Exception
Console.WriteLine(e.Message)
Finally
' Clear the key.
If Not (key Is Nothing) Then
key.Clear()
End If
End Try
End Sub
Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementName As String, ByVal Key As SymmetricAlgorithm)
' Check the arguments.
ArgumentNullException.ThrowIfNull(Doc)
ArgumentNullException.ThrowIfNull(ElementName)
ArgumentNullException.ThrowIfNull(Key)
''''''''''''''''''''''''''''''''''''''''''''''''''
' Find the specified element in the XmlDocument
' object and create a new XmlElemnt object.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(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
' symmetric key.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim eXml As New EncryptedXml()
Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
''''''''''''''''''''''''''''''''''''''''''''''''''
' Construct an EncryptedData object and populate
' it with the desired encryption information.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim edElement As New EncryptedData()
edElement.Type = EncryptedXml.XmlEncElementUrl
' Create an EncryptionMethod element so that the
' receiver knows which algorithm to use for decryption.
' Determine what kind of algorithm is being used and
' supply the appropriate URL to the EncryptionMethod element.
Dim encryptionMethod As String = Nothing
If TypeOf Key Is Aes Then
encryptionMethod = EncryptedXml.XmlEncAES256Url
Else
' Throw an exception if the transform is not in the previous categories
Throw New CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.")
End If
edElement.EncryptionMethod = New EncryptionMethod(encryptionMethod)
' Add the encrypted element data to the
' EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement
''''''''''''''''''''''''''''''''''''''''''''''''''
' Replace the element from the original XmlDocument
' object with the EncryptedData element.
''''''''''''''''''''''''''''''''''''''''''''''''''
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
End Sub
Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As SymmetricAlgorithm)
' Check the arguments.
If Doc Is Nothing Then
Throw New ArgumentNullException("Doc")
End If
If Alg Is Nothing Then
Throw New ArgumentNullException("Alg")
End If
' Find the EncryptedData element in the XmlDocument.
Dim encryptedElement As XmlElement = Doc.GetElementsByTagName("EncryptedData")(0)
' If the EncryptedData element was not found, throw an exception.
If encryptedElement Is Nothing Then
Throw New XmlException("The EncryptedData element was not found.")
End If
' Create an EncryptedData object and populate it.
Dim edElement As New EncryptedData()
edElement.LoadXml(encryptedElement)
' Create a new EncryptedXml object.
Dim exml As New EncryptedXml()
' Decrypt the element using the symmetric key.
Dim rgbOutput As Byte() = exml.DecryptData(edElement, Alg)
' Replace the encryptedData element with the plaintext XML element.
exml.ReplaceData(encryptedElement, rgbOutput)
End Sub
End Module
編譯程式碼
在以 .NET Framework 為目標的專案中,包含
System.Security.dll
的參考。在以 .NET Core 或 .NET 5 為目標的專案中,安裝 NuGet 套件 System.Security.Cryptography.Xml。
包含下列命名空間:System.Xml、System.Security.Cryptography 和 System.Security.Cryptography.Xml。
.NET 安全性
絕對不要以純文字儲存密碼編譯金鑰,或以純文字格式在電腦之間傳輸金鑰。 請改用安全的金鑰容器來儲存密碼編譯金鑰。
當您使用完密碼編譯金鑰,請從記憶體清除它,方法是將每個位元組設定為零,或呼叫 Managed 密碼編譯類別的 Clear 方法。
另請參閱
- 密碼編譯模型 - 描述基底類別程式庫中如何實作密碼編譯。
- 密碼編譯服務
- 跨平台加密
- System.Security.Cryptography.Xml
- 操作說明:使用對稱金鑰解密 XML 元素
- ASP.NET Core 資料保護