概要
- 鍵導出関数であるPBKDF2を使って、「パスワードからAES-256等で使用可能なキー(256ビット)」(パスワードハッシュとしても使用可)を生成するサンプルを紹介します。
- 完全なサンプルコードはgithubで公開しています。GitHub
Contribute to nextdoorwith/example-dotnet6 development by cr…
- 次の実行環境を使用しています。
OS Windows 10(64ビット) IDE Microsoft Visual Studio Community 2022(17.1.3) 言語 C#(10.0) + .NET6 ハードウェア CPU: AMD Ryzen 5 3400G, MEM: 16GB, SSD: 130GB - 次のリファレンスを参考にしています。
鍵導出関数とPBKDF2
- PBKDF2は鍵導出関数と呼ばれ、パスワードからキーを生成するための関数です。
- PBKDF2は古くなりつつあります。可能であれば、より新しいArgon2idの使用をお薦めします。こちらを使用できない場合、LINUX等で使用されているbcrypt等のをお薦めします。
- アメリカ政府機関、金融やセキュリティ系システムで参考とされる「暗号化モジュールのためのセキュリティ要件(FIPS140-2)」では、PBKDF2がサポートされています。Argon2idやbcryptはサポートされていないので、FIPS140-2の準拠を求められるシステムではPBKDF2を使用する必要があります。
推奨パラメータ
- 業務でPBKDF2を使用する場合の推奨パラメータは次の通りです。(2022年8月現在)
説明にある「コード分析」はVisual Studio 2022の.NET コード分析を意味しています。項目 推奨値 根拠など ソルト長 128ビット以上 NIST. SP 800-132.で推奨。 ハッシュアルゴリズム SHA-256以上 OWASP推奨。
MD5やSHA-1は脆弱性があるため。
コード分析ではSHA-256以上が推奨(CA5379)ストレッチング回数
(イテレーション回数)31万回以上 OWASPが推奨するSHA-256使用時の値。
コード分析では10万回以上が推奨(CA5387) - PBKDF2などの鍵導出関数は、CPUやメモリ等のリソースを大量に消費します。性能要件を満たせない場合、前述のストレッチング回数などのパラメータを調整する必要があります。
- パスワードを使用した認証は初回アクセスのみで、その後は発行されたCookieやトークンを使用して認証・認可するのが一般的です。性能劣化を最小限にするために、PBKDF2の使用は初回アクセス時の認証のみに留め、それ以降のアクセスには使用しないような設計になります。
- ささいな抵抗ですが、ストレッチング回数は31万回等のように予測しやすい回数(キリが良い回数)より、313,324回等のようにキリの悪い回数の方が良いかもしれません。
リンク
サンプルコード
- PBKDF2を使用して、パスワードとソルトからパスワードハッシュを生成するサンプルです。
(「鍵導出関数を使用する」という意味では、AES-256等の256ビット長のキーを生成するサンプルとも言えます。)12var salt = Pbkdf2Example.CreatePasswordSalt();var key = Pbkdf2Example.CreateKeyFromPassword("password", salt); - ソルトの生成、PBKDF2によるキー生成のコード部分です。
- 128ビット(16バイト)長のソルトを使用する前提です。ソルトの生成には暗号用の予測が難しいRandomNumberGeneratorクラスを使用します。なお、RNGCryptoServiceProviderは非推奨になりました。
- PBKDF2によるキー生成はRfc2898DeriveBytesクラスを使用します。
- GetBytes()メソッドを使用する方法と、Pbkdf2()というstaticメソッドを使用する方法があります。後者のPbkdf2()メソッドを使う方が性能が良いようです。
(私の環境でキー生成を1,000回繰り返した場合、前者は60秒、後者は40秒程となり、後者のPbkdf2()の方が30%程良い。) - 既定では安全性が低いSHA-1が使用されるので、前述の通りSHA-256を指定しています。また、イテレーション回数はOWASPで推奨される31万回(SHA-256使用時)を指定しています。
- コード分析(セキュリティ規則)が有効になっている場合、イテレーション回数は10万回以上(CA5387)、ハッシュアルゴリズムはSHA-256以上(CA5379)、の警告(推奨)が出力されます。
123456789101112131415161718192021222324public static class Pbkdf2Example{public static byte[] CreatePasswordSalt(){return RandomNumberGenerator.GetBytes(128 / 8);}public static byte[] CreateKeyFromPassword(string password, byte[] salt){return Rfc2898DeriveBytes.Pbkdf2(password,salt,310_000,HashAlgorithmName.SHA256,256 / 8);// using var key = new Rfc2898DeriveBytes(// password,// salt,// 310_000,// HashAlgorithmName.SHA256// );// return key.GetBytes(256/8);}}
リンク