Share via


HOW TO:使用非對稱金鑰解密 XML 項目

更新:2010 年 7 月

您可以使用 System.Security.Cryptography.Xml 命名空間中的類別,加密及解密 XML 文件中的項目。 XML 加密是交換或儲存加密 XML 資料的標準方法,無資料遭竊取之虞。 如需 XML 加密標準的詳細資訊,請參閱全球資訊網協會 (World Wide Web Consortium,W3C) 的 XML 簽章語法和處理 (英文) 建議。

這個程序中的範例會解密 XML 項目,該項目是使用 HOW TO:使用非對稱金鑰加密 XML 項目中所述的方法進行加密。 它會找出 <EncryptedData> 項目、解密此項目,然後再以原始的純文字 XML 項目取代此項目。

這個範例使用兩個金鑰解密 XML 項目。 它會從金鑰容器中擷取先前產生的 RSA 私密金鑰,再用此 RSA 金鑰解密儲存在 <EncryptedData> 項目之 <EncryptedKey> 項目內的工作階段金鑰。 接下來,此範例會使用工作階段金鑰來解密 XML 項目。

當多個應用程式需要共用加密資料,或應用程式在執行之間需要儲存加密資料的情況下,則適用這個範例。

若要使用非對稱金鑰解密 XML 項目

  1. 建立 CspParameters 物件,並指定金鑰容器的名稱。

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
    
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
  2. 使用 RSACryptoServiceProvider 物件從容器中擷取先前產生的非對稱金鑰。 當您將 CspParameters 物件傳遞至 RSACryptoServiceProvider 建構函式時,金鑰會自動從金鑰容器中擷取。

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. 建立新的 EncryptedXml 物件以解密文件。

    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
            // Create a new EncryptedXml object.
            EncryptedXml exml = new EncryptedXml(Doc);
    
  4. 加入金鑰/名稱對應,可以將 RSA 金鑰關聯到要解密之文件中的項目。 您必須使用與加密文件時所使用相同金鑰的名稱。 請注意,這個名稱不同於用來識別步驟 1 中所指定金鑰容器內金鑰的名稱。

    exml.AddKeyNameMapping(KeyName, Alg)
    
            exml.AddKeyNameMapping(KeyName, Alg);
    
  5. 呼叫 DecryptDocument 方法解密 <EncryptedData> 項目。 這個方法使用 RSA 金鑰解密工作階段金鑰,並自動使用工作階段金鑰解密 XML 項目, 也會自動以原始的純文字取代 <EncryptedData> 項目。

    exml.DecryptDocument()
    
            exml.DecryptDocument();
    
  6. 儲存 XML 文件。

    xmlDoc.Save("test.xml")
    
                xmlDoc.Save("test.xml");
    

範例

Imports System
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml



Module Program

    Sub Main(ByVal args() As String)

        ' Create an XmlDocument object.
        Dim xmlDoc As New XmlDocument()

        ' Load an XML file into the XmlDocument object.
        Try
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try
        Dim cspParams As New CspParameters()
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
        ' Get the RSA key from the key container.  This key will decrypt 
        ' a symmetric key that was imbedded in the XML document. 
        Dim rsaKey As New RSACryptoServiceProvider(cspParams)
        Try

            ' Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey")

            ' Save the XML document.
            xmlDoc.Save("test.xml")
            ' Display the encrypted XML to the console.
            Console.WriteLine()
            Console.WriteLine("Decrypted XML:")
            Console.WriteLine()
            Console.WriteLine(xmlDoc.OuterXml)
        Catch e As Exception
            Console.WriteLine(e.Message)
        Finally
            ' Clear the RSA key.
            rsaKey.Clear()
        End Try


        Console.ReadLine()

    End Sub



    Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As RSA, ByVal KeyName As String)
        ' 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
        If KeyName Is Nothing Then
            Throw New ArgumentNullException("KeyName")
        End If 
        ' Create a new EncryptedXml object.
        Dim exml As New EncryptedXml(Doc)
        ' Add a key-name mapping.
        ' This method can only decrypt documents
        ' that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg)
        ' Decrypt the element.
        exml.DecryptDocument()
    End Sub
End Module


using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

class Program
{
    static void Main(string[] args)
    {

        // Create an XmlDocument object.
        XmlDocument xmlDoc = new XmlDocument();

        // Load an XML file into the XmlDocument object.
        try
        {
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY";

        // Get the RSA key from the key container.  This key will decrypt
        // a symmetric key that was imbedded in the XML document.
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        try
        {

            // Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey");

            // Save the XML document.
            xmlDoc.Save("test.xml");

            // Display the encrypted XML to the console.
            Console.WriteLine();
            Console.WriteLine("Decrypted XML:");
            Console.WriteLine();
            Console.WriteLine(xmlDoc.OuterXml);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Clear the RSA key.
            rsaKey.Clear();
        }


        Console.ReadLine();


    }

    public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
    {
        // Check the arguments.
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (Alg == null)
            throw new ArgumentNullException("Alg");
        if (KeyName == null)
            throw new ArgumentNullException("KeyName");
        // Create a new EncryptedXml object.
        EncryptedXml exml = new EncryptedXml(Doc);

        // Add a key-name mapping.
        // This method can only decrypt documents
        // that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg);

        // Decrypt the element.
        exml.DecryptDocument();

    }

}

這個範例假設,在已編譯程式的相同目錄中,有名為 test.xml 的檔案。 它也假設 test.xml 含有使用 HOW TO:使用非對稱金鑰加密 XML 項目中所說明之技巧加密的 XML 項目。

編譯程式碼

安全性

請勿以純文字格式儲存對稱密碼編譯金鑰,也不要將對稱金鑰以純文字形式在電腦之間傳輸。 此外,也請不要以純文字格式儲存或傳輸非對稱金鑰組的私密金鑰。 如需對稱和非對稱密碼編譯金鑰的詳細資訊,請參閱產生加密和解密金鑰

請勿直接將金鑰嵌入原始程式碼內。 使用 Ildasm.exe (MSIL 反組譯工具) 或在文字編輯器 (例如 [記事本]) 中開啟組件,即可輕鬆從組件中讀取內嵌金鑰。

當您完成使用密碼編譯金鑰時,請將每個位元組設為零,或呼叫 Managed 加密類別的 Clear 方法,從記憶體清除密碼編譯金鑰。 密碼編譯金鑰有時可以透過偵錯工具從記憶體讀取,或者如果記憶體位置被分頁至磁碟,則可以從硬碟讀取。

請參閱

工作

HOW TO:使用非對稱金鑰加密 XML 項目

參考

System.Security.Cryptography.Xml

其他資源

XML 加密和數位簽章

變更記錄

日期

記錄

原因

2010 年 7 月

已更正未依順序的範例。

客戶回函。