.NET 暗号化モデル

.NET は、多くの標準的な暗号化アルゴリズムの実装を提供しています。

オブジェクトの継承

.NET 暗号化システムは、拡張可能な派生クラス継承のパターンを実装しています。 階層は次のとおりです。

派生クラスのこのパターンを使用すると、新しいアルゴリズムの追加、または既存アルゴリズムの新規実装の追加を行うことができます。 たとえば、新しい公開キー アルゴリズムを作成するには、AsymmetricAlgorithm クラスから継承します。 特定のアルゴリズムの実装を新しく作成するには、そのアルゴリズムの非抽象派生クラスを作成します。

今後、この継承モデルは、AesGcmShake128 などの新しい種類のプリミティブには使用されません。 これらのアルゴリズムは sealed です。 これらの型に対する拡張パターンや抽象化が必要な場合、抽象化の実装は開発者が行う必要があります。

ワンショット API

.NET 5 以降では、ハッシュと HMAC に対してよりシンプルな API が導入されました。 柔軟性は若干低くなりますが、これらの "ワンショット" API は次のようになりました。

  • 使いやすい (誤用が少ない)
  • 割り当てを減らす、または割り当て不要
  • スレッド セーフ
  • プラットフォームに最適な実装を使用する

ハッシュおよび HMAC プリミティブは、SHA256.HashData のような型の静的 HashData メソッドを介してワンショット API を公開します。 静的 API には、組み込みの拡張メカニズムはありません。 独自のアルゴリズムを実装する場合は、アルゴリズムに似た静的 API も提供することをお勧めします。

RandomNumberGenerator クラスには、暗号化ランダム データを使ってバッファーを作成する、または埋めるための静的メソッドも用意されています。 これらのメソッドでは常に、システムの暗号論的擬似乱数生成器 (CSPRNG) が使用されます。

.NET でのアルゴリズムの実装方法

アルゴリズムに使用できるさまざまな実装例として、対称アルゴリズムを検討します。 すべての対称アルゴリズムの基本は SymmetricAlgorithm です。これは、AesTripleDES、および推奨されなくなったその他のものによって継承されます。

Aes は、AesCryptoServiceProviderAesCngAesManaged により継承されます。

Windows 上の .NET Framework の場合:

  • *CryptoServiceProvider アルゴリズム クラス (AesCryptoServiceProvider など) は、アルゴリズムの Windows Cryptography API (CAPI) 実装のラッパーです。
  • *Cng アルゴリズム クラス (ECDiffieHellmanCng など) は、Windows Cryptography Next Generation (CNG) 実装のラッパーです。
  • クラス AesManaged (*Managed など) は、すべてマネージド コードで記述されています。 *Managed は連邦情報処理規格 (FIPS: Federal Information Processing Standards) によって認定されておらず、*CryptoServiceProvider*Cng ラッパー クラスよりも低速である場合があります。

.NET Core と .NET 5 以降のバージョンでは、すべての実装クラス (*CryptoServiceProvider*Managed*Cng) は、オペレーティング システム (OS) アルゴリズムのラッパーです。 OS アルゴリズムが FIPS によって認定されている場合、.NET は FIPS によって認定されたアルゴリズムを使用します。 詳細については、クロスプラットフォーム暗号化に関するページをご覧ください。

ほとんどの場合、AesCryptoServiceProvider などのアルゴリズム実装クラスを直接参照する必要はありません。 通常、必要とされるメソッドとプロパティは、Aes などの基本アルゴリズム クラスにあります。 基本アルゴリズム クラスのファクトリ メソッドを使用して既定の実装クラスのインスタンスを作成し、基本アルゴリズム クラスを参照します。 たとえば、次の例で強調表示されているコード行をご確認ください。

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

アルゴリズムの選択

データの整合性、データのプライバシー保護、またはキー生成など、さまざまな理由のためにアルゴリズムを選択することができます。 対称アルゴリズムおよびハッシュ アルゴリズムは、整合性の理由 (変更の防止) またはプライバシー上の理由 (表示の防止) のいずれかのためにデータを保護することを意図しています。 ハッシュ アルゴリズムは、主にデータの整合性用に使用されます。

アプリケーションで推奨されるアルゴリズムの一覧を示します。

関連項目