次の方法で共有


.NET 暗号化モデル

.NET には、多くの標準的な暗号アルゴリズムの実装が用意されています。

オブジェクトの継承

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

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

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

一度限りのAPI

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

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

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

RandomNumberGenerator クラスには、暗号化ランダム データでバッファーを作成または入力するための静的メソッドも用意されています。 これらのメソッドでは常に、システムの暗号によってセキュリティで保護された擬似乱数ジェネレーター (CSPRNG) が使用されます。

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

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

Aes は、 AesCryptoServiceProviderAesCng、および AesManagedによって継承されます。

Windows 上の .NET Framework の場合:

  • *CryptoServiceProvider AesCryptoServiceProviderなどのアルゴリズム クラスは、アルゴリズムの Windows Cryptography API (CAPI) 実装のラッパーです。
  • *Cng ECDiffieHellmanCngなどのアルゴリズム クラスは、Windows Cryptography Next Generation (CNG) 実装のラッパーです。
  • *Managed AesManagedなどのクラスは、マネージド コードで完全に記述されます。 *Managed の実装は連邦情報処理標準 (FIPS) の認定を受けず、 *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

アルゴリズムを選択する

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

アプリケーション別の推奨アルゴリズムの一覧を次に示します。

こちらも参照ください