解密資料
解密是加密的反向作業。 針對秘密金鑰加密,您必須同時知道金鑰和用來加密資料的 IV。 針對公開金鑰加密,您必須知道公開金鑰 (如果使用私密金鑰來加密資料) 或私密金鑰 (如果使用公開金鑰來加密資料)。
對稱解密
以對稱演算法加密的資料解密類似於用來以對稱演算法加密資料的程序。 類別 CryptoStream 會與 .NET 所提供的對稱密碼編譯類別搭配使用,以解密從任何 Managed 資料流程物件讀取的資料。
下列範例說明如何為 Aes 演算法建立預設實作類別的新實例。 實例是用來對 CryptoStream 物件執行解密。 此範例會先建立實作 Aes 類別的新實例。 它會從 Managed 資料流程變數 fileStream
讀取初始化向量 (IV) 值。 接下來,它會具現化 CryptoStream 物件,並將其初始化為 實例的值 fileStream
。 SymmetricAlgorithm.CreateDecryptor實例中的 Aes 方法會傳遞 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);