加密資料

對稱式加密和非對稱式加密是使用不同的程序執行。 對稱式加密在資料流上執行,因此適用於加密大量資料。 非對稱式加密在少數的位元組上執行,因此只適用於小量的資料。

對稱加密

Managed 對稱式密碼編譯類別可搭配特殊的資料流類別,稱為 CryptoStream ,它會加密讀入資料流的資料。 CryptoStream 類別初始化時具有 Managed 資料流類別初始化、實作 ICryptoTransform 介面 (從實作密碼編譯演算法的類別建立) 的類別,以及描述允許對 CryptoStreamMode CryptoStream 執行之存取類型的列舉。 CryptoStream 類別可以使用衍生自 Stream 類別的任何類別初始化,包括 FileStreamMemoryStreamNetworkStream。 使用這些類別,您可以在各種不同的資料流物件上執行對稱式加密。

下列範例說明如何建立預設實作 Aes 類別演算法的新執行個體。 執行個體用於執行 CryptoStream 類別的加密。 在此範例中, CryptoStream 以稱為 fileStream 的資料流物件初始化,它是任何類型的 Managed 資料流。 將金鑰和加密所用 IV 傳遞給來自 Aes 類別的 CreateEncryptor 方法。 在此情況下,會使用從 aes 產生的預設金鑰和 IV。

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);

此程式碼執行之後,寫入 CryptoStream 物件的任何資料會使用 AES 演算法進行加密。

下列範例顯示建立資料流、加密資料流、寫入資料流,然後關閉資料流的整個程序。 這個範例會建立使用 CryptoStream 類別和 Aes 類別加密的檔案資料流。 產生的 IV 會寫入至 FileStream 的開頭,因此便可讀取和用於加密。 訊息接著會使用 StreamWriter 類別寫入至加密的資料流。 即使相同金鑰可多次用於加密和解密資料,但仍建議每次產生新的隨機 IV。 如此一來,即使純文字相同時,加密的資料仍一律不同。

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

程式碼會使用 AES 對稱演算法來加密資料流,並將 IV 和加密的 "Hello World!" 寫入至資料流。 如果程式碼成功,則會建立名為 TestData.txt 的加密檔案並在主控台中顯示下列文字:

The file was encrypted.

您可使用解密資料中的對稱解密範例來解密檔案。 該範例和此範例會指定相同金鑰。

不過,如果引發例外狀況,程式碼會在主控台中顯示下列文字:

The encryption failed.

非對稱加密

非對稱演算法通常用來加密少量的資料,例如對稱金鑰和 IV 的加密。 一般來說,個別的執行中非對稱式加密會使用另一個合作對象所產生的公開金鑰。 對此目的,RSA 類別由 .NET 所提供。

下列範例會使用公開金鑰資訊來加密對稱金鑰和 IV。 會初始化兩個代表第三方的公開金鑰的位元組陣列。 RSAParameters 物件會初始化為這些值。 接下來,RSAParameters (以及其所代表的公開金鑰) 的物件會使用 RSA.ImportParameters 方法匯入到 RSA 執行個體。 最後, Aes 類別所建立的私密金鑰和 IV 會被加密。 此範例會要求系統安裝 128 位元加密。

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);
    }
}

另請參閱