概要
この記事では、C# を使って高度な暗号化とメッセージ認証を行う方法を紹介します。この例では、AES 暗号化アルゴリズムを使用し、複数のパスワードと HMAC キーによる二重暗号化を行っています。また、暗号化データの整合性を確認するために HMAC を使用しています。
実装の概要
この実装では、次のような主要な機能を提供します。
- AES 暗号化: データを安全に暗号化するために AES-256 アルゴリズムを使用します。
- PBKDF2 によるキー派生: パスワードから暗号化キーを生成するために PBKDF2 を使用しています。
- 複数のパスワードでの二重暗号化: 暗号化を複数のパスワードを用いて複数回行うことで、セキュリティを強化しています。
- HMAC によるデータの整合性チェック: HMAC (SHA-256 または SHA-512) を使用して、暗号化データの改ざんを検出します。
ソースコードの入手
このライブラリの完全なソースコードはGitHubリポジトリに公開されています。より詳しい実装内容や、他の便利な機能について興味がある方は、以下のリポジトリをご覧ください。
コード解説
1. AES 暗号化と復号化
まず、AES を使って平文を暗号化し、またその逆に復号化するためのメソッドを見てみましょう。
private static byte[] EncryptAes(string plainText, byte[] key, byte[] iv)
{
using var aesAlg = Aes.Create();
aesAlg.Key = key;
aesAlg.IV = iv;
using var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using var msEncrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
return msEncrypt.ToArray();
}
AES 暗号化を行う EncryptAes
メソッドでは、Aes.Create()
を使用して AES のインスタンスを生成し、キーと初期化ベクター (IV) を設定します。その後、CryptoStream
を利用して平文を暗号化します。
2. 二重暗号化の流れ
この実装では、複数のパスワードを使用して二重暗号化を行っています。最初のパスワードで暗号化を行い、その結果を次のパスワードでさらに暗号化するというプロセスを繰り返します。
for (int i = 1; i < passwords.Length; i++)
{
var encryptedText = Convert.ToBase64String(encryptedData);
byte[] key = DeriveKey(passwords[i], salt, hashAlgorithm);
encryptedData = EncryptAes(encryptedText, key, iv);
}
3. HMAC によるデータの整合性チェック
暗号化後のデータに対して HMAC を生成し、その HMAC を用いてデータが改ざんされていないかを確認します。
if (!HmacHelper.VerifyHmac(encryptedData, mac, hmacKey, hashAlgorithm))
{
throw new CryptographicException("データの整合性が確認できません。");
}
HMAC の生成と検証を行う HmacHelper
クラスは、HMACSHA256
または HMACSHA512
を使用して、データの整合性を確認します。
4. 結合データの生成と復元
暗号化データ、Salt、IV、MAC を一つのバイト配列に結合して保存し、復号時にそれらを分離する処理も実装されています。
private static byte[] CombineData(byte[] salt, byte[] iv, byte[] data, byte[] mac, string hmacKey)
{
byte[] result = new byte[salt.Length + iv.Length + data.Length + mac.Length];
Buffer.BlockCopy(salt, 0, result, 0, salt.Length);
Buffer.BlockCopy(iv, 0, result, salt.Length, iv.Length);
Buffer.BlockCopy(data, 0, result, salt.Length + iv.Length, data.Length);
if (!string.IsNullOrEmpty(hmacKey))
{
Buffer.BlockCopy(mac, 0, result, salt.Length + iv.Length + data.Length, mac.Length);
}
return result;
}
復号時には、このバイト配列から必要な情報を抽出し、復号化を行います。
まとめ
この実装により、複数のパスワードと HMAC を使用した安全性の高いデータ暗号化が可能になります。セキュリティが重要なアプリケーションにおいて、データの暗号化と整合性チェックは非常に重要です。このコードを活用して、自分のプロジェクトにおけるデータセキュリティを強化してください。