Dešifrování dat
Dešifrování je reverzní operace k šifrování. Pro šifrování s tajným klíčem je třeba znát jak klíč, tak i inicializační vektor (IV), které byly použity k zašifrování dat. Pro šifrování s veřejným klíčem je třeba znát veřejný klíč (v případě, že data byla zašifrována pomocí privátního klíče) nebo privátní klíč (v případě, že data byla zašifrována pomocí veřejného klíče).
Symetrické dešifrování
Dešifrování dat zašifrovaných pomocí symetrických algoritmů je podobný proces, jaký se používá k šifrování dat symetrickými algoritmy. Třída CryptoStream společně s třídami pro symetrické šifrování poskytovanými rozhraním .NET Framework slouží k dešifrování dat přečtených z libovolné instance spravovaného datového proudu.
Následující příklad ukazuje, jak vytvořit novou instanci třídy RijndaelManaged a použít ji k dešifrování na objektu CryptoStream. V tomto příkladu je nejprve vytvořena nová instance třídy RijndaelManaged. Poté je vytvořen objekt CryptoStream a je inicializován se spravovaným datovým proudem nazvaným MyStream. Dále je metodě CreateDecryptor z třídy RijndaelManaged předán stejný klíč a IV, které byly použity k šifrování a výsledek je pak předán konstruktoru CryptoStream. Nakonec je konstruktoru CryptoStream předán výčet CryptoStreamMode.Read, který udává přístup ke čtení datového proudu.
Dim RMCrypto As New RijndaelManaged()
Dim CryptStream As New CryptoStream(MyStream, RMCrypto.CreateDecryptor(RMCrypto.Key, RMCrypto.IV), CryptoStreamMode.Read)
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream CryptStream = new CryptoStream(MyStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);
Následující příklad zobrazuje celý proces vytváření datového proudu, dešifrování datového proudu, čtení z datového proudu a zavření datových proudů. Je vytvořen objekt TCPListener, který inicializuje síťový datový proud v okamžiku, kdy je na naslouchající objekt vytvořeno spojení. Síťový datový proud je potom dešifrován pomocí třídy CryptoStream a třídy RijndaelManaged. Tento příklad předpokládá, že klíč a IV byly buď již úspěšně přeneseny nebo dříve dohodnuty. Nezobrazuje kód potřebný k zašifrování a přenosu těchto hodnot.
Imports System
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Imports System.Net
Imports System.Security.Cryptography
Module Module1
Sub Main()
'The key and IV must be the same values that were 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}
Dim IV As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
Try
'Initialize a TCPListener on port 11000
'using the current IP address.
Dim TCPListen As New TcpListener(IPAddress.Any, 11000)
'Start the listener.
TCPListen.Start()
'Check for a connection every five seconds.
While Not TCPListen.Pending()
Console.WriteLine("Still listening. Will try in 5 seconds.")
Thread.Sleep(5000)
End While
'Accept the client if one is found.
Dim TCP As TcpClient = TCPListen.AcceptTcpClient()
'Create a network stream from the connection.
Dim NetStream As NetworkStream = TCP.GetStream()
'Create a new instance of the RijndaelManaged class
'and decrypt the stream.
Dim RMCrypto As New RijndaelManaged()
'Create an instance of the CryptoStream class, pass it the NetworkStream, and decrypt
'it with the Rijndael class using the key and IV.
Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read)
'Read the stream.
Dim SReader As New StreamReader(CryptStream)
'Display the message.
Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd())
'Close the streams.
SReader.Close()
NetStream.Close()
TCP.Close()
'Catch any exceptions.
Catch
Console.WriteLine("The Listener Failed.")
End Try
End Sub
End Module
using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
using System.Security.Cryptography;
class Class1
{
static void Main(string[] args)
{
//The key and IV must be the same values that were used
//to encrypt the stream.
byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
try
{
//Initialize a TCPListener on port 11000
//using the current IP address.
TcpListener TCPListen = new TcpListener(IPAdress.Any, 11000);
//Start the listener.
TCPListen.Start();
//Check for a connection every five seconds.
while(!TCPListen.Pending())
{
Console.WriteLine("Still listening. Will try in 5 seconds.");
Thread.Sleep(5000);
}
//Accept the client if one is found.
TcpClient TCP = TCPListen.AcceptTcpClient();
//Create a network stream from the connection.
NetworkStream NetStream = TCP.GetStream();
//Create a new instance of the RijndaelManaged class
// and decrypt the stream.
RijndaelManaged RMCrypto = new RijndaelManaged();
//Create a CryptoStream, pass it the NetworkStream, and decrypt
//it with the Rijndael class using the key and IV.
CryptoStream CryptStream = new CryptoStream(NetStream,
RMCrypto.CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
//Read the stream.
StreamReader SReader = new StreamReader(CryptStream);
//Display the message.
Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd());
//Close the streams.
SReader.Close();
NetStream.Close();
TCP.Close();
}
//Catch any exceptions.
catch
{
Console.WriteLine("The Listener Failed.");
}
}
}
Aby byla předchozí ukázka funkční, musí být vytvořeno šifrované připojení k naslouchající straně. Připojení musí používat stejný klíč, IV a algoritmus, jaký je používán na naslouchající straně. Pokud je toto připojení vytvořeno, je zpráva dešifrována a zobrazena v konzole.
Asymetrické dešifrování
Jedna strana (strana A) obvykle generuje jak veřejný, tak i privátní klíč a uloží je v paměti nebo v kontejneru kryptografických klíčů. Poté strana A odešle veřejný klíč druhé straně (straně B). Strana B zašifruje pomocí veřejného klíče data a odešle je straně A. Po obdržení dat strana A data dešifruje pomocí odpovídajícího soukromého klíče. Dešifrování bude úspěšné, jen pokud strana A používá soukromý klíč odpovídající veřejnému klíči, který strana B použila k zašifrování dat.
Informace o ukládání asymetrického klíče v zabezpečeném kontejneru kryptografických klíčů a pozdějším načítání asymetrického klíče naleznete v tématu Postupy: Uložení asymetrického klíče v kontejneru klíčů.
Následující příklad provádí dešifrování dvou polí bajtů, které představují symetrický klíč a IV. Další informace o extrahování veřejného asymetrického klíče z objektu RSACryptoServiceProvider ve formátu, který lze snadno odeslat třetí straně, naleznete v tématu Šifrování dat.
'Create a new instance of the RSACryptoServiceProvider class.
Dim RSA As New RSACryptoServiceProvider()
' 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, False)
SymmetricIV = RSA.Decrypt(EncryptedSymmetricIV, False)
//Create a new instance of the RSACryptoServiceProvider class.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
// 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, false);
SymmetricIV = RSA.Decrypt( EncryptedSymmetricIV , false);
Viz také
Koncepty
Generování klíčů pro šifrování a dešifrování