解密資料

解密是加密的反向作業。 針對秘密金鑰加密,您必須同時知道金鑰和用來加密資料的 IV。 針對公開金鑰加密,您必須知道公開金鑰 (如果使用私密金鑰來加密資料) 或私密金鑰 (如果使用公開金鑰來加密資料)。

對稱解密

以對稱演算法加密的資料解密類似於用來以對稱演算法加密資料的程序。 CryptoStream 類別與 .NET 所提供的對稱式加密類別一起用來解密從任何受控資料流物件讀取的資料。

下列範例說明如何建立預設實作 Aes 類別演算法的新執行個體。 執行個體可用來對 CryptoStream 物件執行解密。 此範例會先建立 Aes 實作類別的新執行個體。 該執行個體會從 Managed 資料流程變數 fileStream 讀取初始化向量 (IV) 值。 接下來會具現化 CryptoStream 物件,並將其初始化為 fileStream 執行個體的值。 來自 Aes 執行個體的 SymmetricAlgorithm.CreateDecryptor 方法會傳遞 IV 值,以及用於加密的相同金鑰。

Dim aes As Aes = Aes.Create()
Dim cryptStream As New CryptoStream(
    fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)
Aes aes = Aes.Create();
CryptoStream cryptStream = new CryptoStream(
    fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read);

下列範例顯示建立資料流、解密資料流、從資料流讀取,然後關閉資料流的整個程序。 系統會建立檔案資料流程物件,以讀取名為 TestData.txt 的檔案。 接著會使用 CryptoStream 類別和 Aes 類別解密檔案資料流。 此範例會指定加密資料對稱加密範例中使用的金鑰值。 它不會顯示加密和傳輸這些值所需的程式碼。

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.Open))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] iv = new byte[aes.IV.Length];
            int numBytesToRead = aes.IV.Length;
            int numBytesRead = 0;
            while (numBytesToRead > 0)
            {
                int n = fileStream.Read(iv, numBytesRead, numBytesToRead);
                if (n == 0) break;

                numBytesRead += n;
                numBytesToRead -= n;
            }

            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };

            using (CryptoStream cryptoStream = new(
               fileStream,
               aes.CreateDecryptor(key, iv),
               CryptoStreamMode.Read))
            {
                // By default, the StreamReader uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamReader(cryptoStream, Encoding.Unicode).
                using (StreamReader decryptReader = new(cryptoStream))
                {
                    string decryptedMessage = await decryptReader.ReadToEndAsync();
                    Console.WriteLine($"The decrypted original message: {decryptedMessage}");
                }
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"The decryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        ' Decryption key must be the same value that was used
        ' to encrypt the stream.
        Dim key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}

        Try
            ' Create a file stream.
            Using fileStream As New FileStream("TestData.txt", FileMode.Open)

                ' Create a new instance of the default Aes implementation class
                Using aes As Aes = Aes.Create()

                    ' Reads IV value from beginning of the file.
                    Dim iv As Byte() = New Byte(aes.IV.Length - 1) {}
                    Dim numBytesToRead As Integer = CType(aes.IV.Length, Integer)
                    Dim numBytesRead As Integer = 0

                    While (numBytesToRead > 0)
                        Dim n As Integer = fileStream.Read(iv, numBytesRead, numBytesToRead)
                        If n = 0 Then
                            Exit While
                        End If
                        numBytesRead += n
                        numBytesToRead -= n
                    End While

                    Using cryptoStream As New CryptoStream(fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)

                        ' By default, the StreamReader uses UTF-8 encoding.
                        ' To change the text encoding, pass the desired encoding as the second parameter.
                        ' For example, New StreamReader(cryptoStream, Encoding.Unicode).
                        Using decryptReader As New StreamReader(cryptoStream)

                            ' Display the message.
                            Console.WriteLine($"The decrypted original message: {decryptReader.ReadToEnd()}")
                        End Using
                    End Using
                End Using
            End Using
        Catch
            Console.WriteLine("The decryption Failed.")
            Throw
        End Try
    End Sub
End Module

上述範例會使用相同的金鑰,以及加密資料對稱加密範例中使用的演算法。 該演算法會解密該範例所建立的 TestData.txt 檔案,並在主控台上顯示原始文字。

非對稱解密

一般而言,有一方 (A 方) 會同時產生公開和私密金鑰,並將金鑰儲存在記憶體或密碼編譯金鑰容器中。 A 方接著會將公開金鑰傳送給另一方 (B 方)。 使用公開金鑰時,B 方會加密資料並將資料傳回 A 方。在收到資料之後,A 方會使用對應的私密金鑰將資料解密。 只有在 A 方使用的私密金鑰對應於 B 方用來加密資料的公開金鑰時,解密才會成功。

如需如何在安全的密碼編譯金鑰容器儲存非對稱金鑰,以及稍後如何擷取非對稱金鑰的相關資訊,請參閱 How to: Store Asymmetric Keys in a Key Container

下列範例說明代表對稱金鑰和 IV 的兩個位元組陣列的解密。 如需如何從 RSA 物件擷取非對稱式公開金鑰,且使用的格式可以輕鬆地傳送給第三方的相關資訊,請參閱 Encrypting Data的 Managed 資料流的值。

'Create a new instance of the RSA class.
Dim rsa As RSA = RSA.Create()

' Export the public key information and send it to a third party.
' Wait for the third party to encrypt some data and send it back.

'Decrypt the symmetric key and IV.
symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.Pkcs1)
symmetricIV = rsa.Decrypt(encryptedSymmetricIV, RSAEncryptionPadding.Pkcs1)
//Create a new instance of the RSA class.
RSA rsa = RSA.Create();

// Export the public key information and send it to a third party.
// Wait for the third party to encrypt some data and send it back.

//Decrypt the symmetric key and IV.
symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.Pkcs1);
symmetricIV = rsa.Decrypt(encryptedSymmetricIV , RSAEncryptionPadding.Pkcs1);

另請參閱