.NET には、多くの標準的な暗号アルゴリズムの実装が用意されています。
オブジェクトの継承
.NET 暗号化システムは、派生クラス継承の拡張可能なパターンを実装します。 階層は次のとおりです。
アルゴリズム型クラス ( SymmetricAlgorithm、 AsymmetricAlgorithm、 HashAlgorithmなど)。 このレベルは抽象です。
アルゴリズム型クラス ( Aes、 RSA、 ECDiffieHellmanなど) から継承するアルゴリズム クラス。 このレベルは抽象です。
AesManaged、RC2CryptoServiceProvider、ECDiffieHellmanCngなど、アルゴリズム クラスから継承するアルゴリズム クラスの実装。 このレベルは完全に実装されています。
派生クラスのこのパターンでは、新しいアルゴリズムまたは既存のアルゴリズムの新しい実装を追加できます。 たとえば、新しい公開キー アルゴリズムを作成するには、 AsymmetricAlgorithm クラスから継承します。 特定のアルゴリズムの新しい実装を作成するには、そのアルゴリズムの非抽象派生クラスを作成します。
今後、この継承モデルは、 AesGcm や Shake128などの新しい種類のプリミティブには使用されません。 これらのアルゴリズムは sealed
。 これらの型に対する拡張性パターンまたは抽象化が必要な場合、抽象化の実装は開発者の責任です。
一度限りのAPI
.NET 5 以降では、ハッシュと HMAC に対してよりシンプルな API が導入されました。 柔軟性は若干低くなりますが、これらの ワンショット API は次のとおりです。
- 使いやすくなっています (誤用が少なくなります)
- 割り当てを減らすか、割り当て不要
- スレッド セーフか
- プラットフォームに最適な実装を使用する
ハッシュおよび HMAC プリミティブは、型の静的 HashData
メソッド ( SHA256.HashData など) を介してワンショット API を公開します。 静的 API には、組み込みの拡張メカニズムはありません。 独自のアルゴリズムを実装する場合は、アルゴリズムの同様の静的 API も提供することをお勧めします。
RandomNumberGenerator クラスには、暗号化ランダム データでバッファーを作成または入力するための静的メソッドも用意されています。 これらのメソッドでは常に、システムの暗号によってセキュリティで保護された擬似乱数ジェネレーター (CSPRNG) が使用されます。
.NET でのアルゴリズムの実装方法
アルゴリズムで使用できるさまざまな実装の例として、対称アルゴリズムを検討してください。 すべての対称アルゴリズムの基本は SymmetricAlgorithmであり、 Aes、 TripleDES、および推奨されなくなったその他のアルゴリズムによって継承されます。
Aes は、 AesCryptoServiceProvider、 AesCng、および 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
アルゴリズムを選択する
データの整合性、データのプライバシー、キーの生成など、さまざまな理由でアルゴリズムを選択できます。 対称アルゴリズムとハッシュ アルゴリズムは、整合性の理由 (変更から保護) またはプライバシー上の理由 (表示から保護) のいずれかでデータを保護することを目的としています。 ハッシュ アルゴリズムは、主にデータ整合性のために使用されます。
アプリケーション別の推奨アルゴリズムの一覧を次に示します。
- データのプライバシー:
- データの整合性:
- デジタル署名:
- キー交換:
- 乱数の生成:
- パスワードからのキーの生成:
こちらも参照ください
.NET