2009年1月14日水曜日

[.NET]ハッシュ(MD5,SHA)

システム上、ユーザに入力されたパスワードのようなデータを定義ファイルやレジストリに保存しておきたい場合があります。しかし平文でおいておくと、第三者がそのファイルより情報を盗み見ることができます。結果本人に成りすましてシステムを悪用することも可能になります。
そのため、パスワードを人が読めない形式に変換して保存しておくなどの工夫が必要になります。
MD5やSHAはハッシュのアルゴリズムで、特定の情報を可逆変換不可能な値に変換することができます。そして同じインプットであれば同じ結果となります。コレを利用し、以下のような手順で処理を実現します。
  1. ユーザにパスワードを入力してもらう
  2. MD5やSHAでハッシュした情報を定義ファイルに保存する

そして、再度認証が必要な場合、

  1. ユーザにパスワードを入力してもらう
  2. 入力値をMD5やSHAでハッシュする
  3. 定義ファイルよりハッシュしたパスワードを取得する
  4. 2と3を比較して同じなら認証成功

というかんじ。.NET Frameworkでは、MD5やSHAをはじめいくつかのハッシュアルゴリズム提供されています。以下では、MD5,SHA,SHA512を使ってハッシュしています。コードはこんな感じ。



■ハッシュ
(ボタン押下の処理です。txtOriginalとtxtHashはTextBox)
//using System.Security.Cryptography;


/// <summary>
/// MD5ハッシュ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnMD5H_Click(object senderEventArgs e)
{
    //入力値よりUTF8のバイト列を取得する
    byte[] data = Encoding.UTF8.GetBytes(txtOriginal.Text);

    //ハッシュする
    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
    {
        string code = byte2HexString(md5.ComputeHash(data));
        txtHash.Text = code;
    }

}

/// <summary>
/// SHAハッシュ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSHAH_Click(object senderEventArgs e)
{
    //入力値よりUTF8のバイト列を取得する
    byte[] data = Encoding.UTF8.GetBytes(txtOriginal.Text);

    //ハッシュする
    using (SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider())
    {
        string code = byte2HexString(sha.ComputeHash(data));
        txtHash.Text = code;
    }

}

/// <summary>
/// SHA512ハッシュ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSHA512H_Click(object senderEventArgs e)
{
    //入力値よりUTF8のバイト列を取得する
    byte[] data = Encoding.UTF8.GetBytes(txtOriginal.Text);

    //ハッシュする
    using (SHA512Managed sha = new SHA512Managed())
    {
        string code = byte2HexString(sha.ComputeHash(data));
        txtHash.Text = code;
    }
}


■文字列・バイト列操作の共通メソッド
/// <summary>
/// 16進数の文字列をバイト列に変換する
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private byte[] hexString2Byte(string data)
{

    int size = data.Length / 2;
    byte[] result = new byte[size];

    //2文字ずつ進み、バイトに変換
    for (int i = 0i < sizei++)
    {
        string target = data.Substring(i * 22);
        result[i] = Convert.ToByte(target16);
    }

    return result;
}

/// <summary>
/// バイト列を16進数の文字列に変換する
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private string byte2HexString(byte[] data)
{
    //00-11-22形式を001122に変換
    return BitConverter.ToString(data).Replace("-""");
}

0 件のコメント :