NDW

アプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

.NET Core(C#) 1. システムエンジニアリング 実装技術 設計技術

C#: パスワードハッシュ生成サンプル(PBKDF2)

投稿日:2022年9月9日 更新日:

概要

鍵導出関数とPBKDF2

  • PBKDF2は鍵導出関数と呼ばれ、パスワードからキーを生成するための関数です。
    • ブルートフォース等の攻撃に対抗できるよう、予測が難しく、キー生成に時間がかかる(CPUやメモリ負荷が高い)アルゴリズムが使用されています。
    • 生成されたキーは、パスワードハッシュやAES256等のキーにも使用できます。
    • PBKDF2は、RSAのPKCS #5 v2.0として規格化され、RFC2898として発行されています。RFC2898は2017年に発行されたRFC8018(PKCS #5 v2.1)で置き換えられています。
  • 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ビット長のキーを生成するサンプルとも言えます。)
    var 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)、の警告(推奨)が出力されます。
    public 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);
        }
    }
    







-.NET Core(C#), 1. システムエンジニアリング, 実装技術, 設計技術

関連記事

Javaによるzipファイルの安全な解凍方法

以前、業務アプリ(Java)でzipファイルの操作が必要となったため、Javaにおけるzip圧縮解凍について調査しました。また、zip4jを使った圧縮・解凍についても説明しました。 ここでは、もう少し …

grid

Excelで月初日、第1週日、第2週日を算出する

プロジェクト管理で毎年、毎月のタスクを管理するために、この辺の操作を行うためのExcel関数を調べたので記載しておきます。 Excelの関数式 ここでは、基本的に5営業日単位で管理したいことと、最初の …

AzureAD B2Cユーザアカウントの操作方法(PowerShell)

Microsoft Graph APIを使ってAzureAD B2Cユーザアカウントを操作するようなアプリケーションを開発しています。 テストエビデンスの取得のために、Microsoft Graph …

Windows Updateが終わらない問題

ふと会社で使っているPCのWindows Updateがほとんど当たっていないことに気づいた。 手動でWindows Updateを実行すると、30分、1時間たっても終わらない… これは何 …

vbaでのエンコード/デコードのサンプル

Excel(vba)で、MD5/SHA-1/SHA-2(SHA-256)の出力、Hex/Base64エンコード/デコードを調べたので備忘録として残します。 動作検証した環境は、Windows10+Of …