Szyfrowanie danych
Szyfrowanie symetryczne i szyfrowanie asymetryczne są wykonywane przy użyciu różnych procesów. Szyfrowanie symetryczne jest wykonywane na strumieniach i dlatego jest przydatne do szyfrowania dużych ilości danych. Szyfrowanie asymetryczne jest wykonywane na niewielkiej liczbie bajtów i dlatego jest przydatne tylko w przypadku małych ilości danych.
Szyfrowanie symetryczne
Zarządzane klasy kryptografii symetrycznej są używane z specjalną klasą strumienia o nazwie a CryptoStream , która szyfruje dane odczytywane do strumienia. Klasa CryptoStream jest inicjowana za pomocą klasy zarządzanego strumienia, klasy, która implementuje ICryptoTransform interfejs (utworzony na podstawie klasy implementującego algorytm kryptograficzny) oraz CryptoStreamMode wyliczenie opisujące typ dostępu dozwolonego dla CryptoStream. Klasę CryptoStream można zainicjować przy użyciu dowolnej klasy, która pochodzi z Stream klasy , w tym FileStream, MemoryStreami NetworkStream. Za pomocą tych klas można wykonywać szyfrowanie symetryczne na różnych obiektach strumienia.
W poniższym przykładzie pokazano, jak utworzyć nowe wystąpienie domyślnej klasy implementacji dla algorytmu Aes . Wystąpienie służy do szyfrowania w klasie CryptoStream . W tym przykładzie element CryptoStream jest inicjowany za pomocą obiektu strumienia o nazwie fileStream
, który może być dowolnym typem zarządzanego strumienia. Metoda CreateEncryptor z klasy Aes jest przekazywana klucz i IV, które są używane do szyfrowania. W tym przypadku używany jest klucz domyślny i IV wygenerowany z aes
.
Dim aes As Aes = Aes.Create()
Dim cryptStream As New CryptoStream(
fileStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write)
Aes aes = Aes.Create();
CryptoStream cryptStream = new CryptoStream(
fileStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write);
Po wykonaniu tego kodu wszystkie dane zapisane w obiekcie CryptoStream są szyfrowane przy użyciu algorytmu AES.
Poniższy przykład przedstawia cały proces tworzenia strumienia, szyfrowania strumienia, zapisywania w strumieniu i zamykania strumienia. W tym przykładzie tworzony jest strumień plików zaszyfrowany przy użyciu klasy CryptoStream i klasy Aes . Wygenerowany iv jest zapisywany na początku FileStreamelementu , więc można go odczytać i użyć do odszyfrowywania. Następnie komunikat jest zapisywany w zaszyfrowanym strumieniu z klasą StreamWriter . Chociaż ten sam klucz może być używany wiele razy do szyfrowania i odszyfrowywania danych, zaleca się wygenerowanie nowego losowego IV za każdym razem. Dzięki temu zaszyfrowane dane są zawsze różne, nawet jeśli zwykły tekst jest taki sam.
using System.Security.Cryptography;
try
{
using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
{
using (Aes aes = Aes.Create())
{
byte[] key =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
};
aes.Key = key;
byte[] iv = aes.IV;
fileStream.Write(iv, 0, iv.Length);
using (CryptoStream cryptoStream = new(
fileStream,
aes.CreateEncryptor(),
CryptoStreamMode.Write))
{
// By default, the StreamWriter uses UTF-8 encoding.
// To change the text encoding, pass the desired encoding as the second parameter.
// For example, new StreamWriter(cryptoStream, Encoding.Unicode).
using (StreamWriter encryptWriter = new(cryptoStream))
{
encryptWriter.WriteLine("Hello World!");
}
}
}
}
Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
Console.WriteLine($"The encryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography
Module Module1
Sub Main()
Try
' Create a file stream
Using fileStream As New FileStream("TestData.txt", FileMode.OpenOrCreate)
' Create a new instance of the default Aes implementation class
' and configure encryption key.
Using aes As Aes = Aes.Create()
'Encryption key used to encrypt the stream.
'The same value must be used to encrypt and decrypt the stream.
Dim key As Byte() = {
&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8,
&H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16
}
aes.Key = key
' Stores IV at the beginning of the file.
' This information will be used for decryption.
Dim iv As Byte() = aes.IV
fileStream.Write(iv, 0, iv.Length)
' Create a CryptoStream, pass it the FileStream, and encrypt
' it with the Aes class.
Using cryptoStream As New CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write)
' By default, the StreamWriter uses UTF-8 encoding.
' To change the text encoding, pass the desired encoding as the second parameter.
' For example, New StreamWriter(cryptoStream, Encoding.Unicode).
Using sWriter As New StreamWriter(cryptoStream)
'Write to the stream.
sWriter.WriteLine("Hello World!")
End Using
End Using
End Using
End Using
'Inform the user that the message was written
'to the stream.
Console.WriteLine("The text was encrypted.")
Catch
'Inform the user that an exception was raised.
Console.WriteLine("The encryption failed.")
Throw
End Try
End Sub
End Module
Kod szyfruje strumień przy użyciu algorytmu symetrycznego AES i zapisuje iv, a następnie szyfruje strumień "Hello World!". Jeśli kod zakończy się pomyślnie, utworzy zaszyfrowany plik o nazwie TestData.txt i wyświetli następujący tekst w konsoli:
The file was encrypted.
Plik można odszyfrować przy użyciu przykładu odszyfrowywania symetrycznego w temacie Odszyfrowywanie danych. W tym przykładzie i w tym przykładzie określono ten sam klucz.
Jeśli jednak zostanie zgłoszony wyjątek, kod wyświetli następujący tekst w konsoli:
The encryption failed.
Szyfrowanie asymetryczne
Algorytmy asymetryczne są zwykle używane do szyfrowania małych ilości danych, takich jak szyfrowanie klucza symetrycznego i IV. Zazwyczaj osoba wykonująca szyfrowanie asymetryczne używa klucza publicznego wygenerowanego przez inną firmę. W RSA tym celu klasa jest dostarczana przez platformę .NET.
W poniższym przykładzie użyto informacji o kluczu publicznym do szyfrowania klucza symetrycznego i IV. Zainicjowano dwie tablice bajtów reprezentujące klucz publiczny innej firmy. Obiekt RSAParameters jest inicjowany do tych wartości. Następnie obiekt RSAParameters (wraz z kluczem publicznym, który reprezentuje) jest importowany do wystąpienia RSA przy użyciu RSA.ImportParameters metody . Na koniec klucz prywatny i IV utworzony przez klasę Aes są szyfrowane. W tym przykładzie wymagane jest zainstalowanie szyfrowania 128-bitowego w systemach.
Imports System
Imports System.Security.Cryptography
Module Module1
Sub Main()
'Initialize the byte arrays to the public key information.
Dim modulus As Byte() = {214, 46, 220, 83, 160, 73, 40, 39, 201, 155, 19, 202, 3, 11, 191, 178, 56, 74, 90, 36, 248, 103, 18, 144, 170, 163, 145, 87, 54, 61, 34, 220, 222, 207, 137, 149, 173, 14, 92, 120, 206, 222, 158, 28, 40, 24, 30, 16, 175, 108, 128, 35, 230, 118, 40, 121, 113, 125, 216, 130, 11, 24, 90, 48, 194, 240, 105, 44, 76, 34, 57, 249, 228, 125, 80, 38, 9, 136, 29, 117, 207, 139, 168, 181, 85, 137, 126, 10, 126, 242, 120, 247, 121, 8, 100, 12, 201, 171, 38, 226, 193, 180, 190, 117, 177, 87, 143, 242, 213, 11, 44, 180, 113, 93, 106, 99, 179, 68, 175, 211, 164, 116, 64, 148, 226, 254, 172, 147}
Dim exponent As Byte() = {1, 0, 1}
'Create values to store encrypted symmetric keys.
Dim encryptedSymmetricKey() As Byte
Dim encryptedSymmetricIV() As Byte
'Create a new instance of the default RSA implementation class.
Dim rsa As RSA = RSA.Create()
'Create a new instance of the RSAParameters structure.
Dim rsaKeyInfo As New RSAParameters()
'Set rsaKeyInfo to the public key values.
rsaKeyInfo.Modulus = modulus
rsaKeyInfo.Exponent = exponent
'Import key parameters into rsa
rsa.ImportParameters(rsaKeyInfo)
'Create a new instance of the default Aes implementation class.
Dim aes As Aes = Aes.Create()
'Encrypt the symmetric key and IV.
encryptedSymmetricKey = rsa.Encrypt(aes.Key, RSAEncryptionPadding.Pkcs1)
encryptedSymmetricIV = rsa.Encrypt(aes.IV, RSAEncryptionPadding.Pkcs1)
End Sub
End Module
using System;
using System.Security.Cryptography;
class Class1
{
static void Main()
{
//Initialize the byte arrays to the public key information.
byte[] modulus =
{
214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
106,99,179,68,175,211,164,116,64,148,226,254,172,147
};
byte[] exponent = { 1, 0, 1 };
//Create values to store encrypted symmetric keys.
byte[] encryptedSymmetricKey;
byte[] encryptedSymmetricIV;
//Create a new instance of the RSA class.
RSA rsa = RSA.Create();
//Create a new instance of the RSAParameters structure.
RSAParameters rsaKeyInfo = new RSAParameters();
//Set rsaKeyInfo to the public key values.
rsaKeyInfo.Modulus = modulus;
rsaKeyInfo.Exponent = exponent;
//Import key parameters into rsa.
rsa.ImportParameters(rsaKeyInfo);
//Create a new instance of the default Aes implementation class.
Aes aes = Aes.Create();
//Encrypt the symmetric key and IV.
encryptedSymmetricKey = rsa.Encrypt(aes.Key, RSAEncryptionPadding.Pkcs1);
encryptedSymmetricIV = rsa.Encrypt(aes.IV, RSAEncryptionPadding.Pkcs1);
}
}