41
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#, .NET Core でパスワードなどの文字列をハッシュ化する

Last updated at Posted at 2019-11-11

環境

.NET Core Sdk 3.0.100、C# の言語バージョンは 8 です。

$ dotnet --version
3.0.100

自前でハッシュ化する

DB にパスワードを保存する際、セキュリティのため平文のままではなくハッシュ化してから保存したい場合があります。
下記は文字列をハッシュ関数SHA-256で暗号化する例です。

// using System.Linq;
// using System.Security.Cryptography;
// using System.Text;

string password = "ハッシュ化したいテキスト";

// SHA256 デフォルト実装のインスタンスを呼び出します。
using SHA256 sha256 = SHA256.Create(); 

// 文字列をバイト配列にエンコードします。
byte[] encoded = Encoding.UTF8.GetBytes(password);

// ハッシュ値を計算します。
byte[] hash = sha256.ComputeHash(encoded);

// ハッシュ値を 16 進数文字列に変換します。書き方がちょっと面倒。
// System.BitConverter.ToString(hash).Replace("-", "").ToLower() と同じ。
// 16 進数文字列でなく Base64 文字列に変換する場合 -> System.Convert.ToBase64String(hash) で OK。
// 各要素を 16 進数文字列に変換して結合しています。
string hashed = string.Concat(hash.Select(b => $"{b:x2}")); // -> 93541bd68ccf06f3d4f9cf56a3ca415f1d2d315f3f672ecec9f52b0c7c3ad9fc

Microsoft.AspNetCore.Cryptography.KeyDerivationでハッシュ化する

ただし、上記のような1度だけのハッシュ化では脆弱であるため、

  • パスワードにソルトを付与して、その結果をハッシュ化する
  • ハッシュ化した結果をさらに何重にもハッシュ化する

する必要があります。

そのための便利な関数が用意されてるパッケージをインストールします。

$ dotnet add package Microsoft.AspNetCore.Cryptography.KeyDerivation
// using Microsoft.AspNetCore.Cryptography.KeyDerivation;
// using System.Linq;
// using System.Security.Cryptography;

string password = "ハッシュ化したいテキスト";

// ソルトを作成する。
byte[] salt = new byte[128 / 8];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(salt);

// Pbkdf2 メソッドではハッシュ化する反復回数や作成するハッシュの長さを指定することができます。
// OS をよって最適化された実装が選択され、自前で実装するよりもパフォーマンスが向上するそうです。
// https://docs.microsoft.com/ja-jp/aspnet/core/security/data-protection/consumer-apis/password-hashing?view=aspnetcore-3.0
byte[] hash = KeyDerivation.Pbkdf2(
  password,
  salt,
  prf: KeyDerivationPrf.HMACSHA256,
  iterationCount: 10000,  // 反復回数
  numBytesRequested: 256 / 8);  // ハッシュの長さ

// ハッシュ値を 16 進数文字列に変換します。
string hashed = string.Concat(hash.Select(b => $"{b:x2}")); // -> 93541bd68ccf06f3d4f9cf56a3ca415f1d2d315f3f672ecec9f52b0c7c3ad9fc

実際の Web アプリケーションを開発する際にはKeyDerivation.Pbkdf2を使うことになると思います。

41
41
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?