2009年1月19日月曜日

[.NET]文字列の暗号化(3DES)

MD5などのハッシュアルゴリズムは可逆変換ができない(前提である)ことと、常に同じ結果が出ることを利用し、符号化した情報を照合するという方法を取っていますが、今回は他システム連携する場合に、その他システム用のパスワードを保存したい場合に利用する暗号化について書きます。
.NET Frameworkではいくつか暗号化のアルゴリズムが提供されています。以下では3DES(トリプルDES)を利用した暗号化を実施しています。

しかし、3DESではどこかしらに暗号用のキー情報を保持する必要があり、その点が問題として残ります。コードはこんなかんじ。

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

string key = "123456789ABCDEF123454678";
string vec = "12345678";

/// <summary>
/// 3DES暗号化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn3DESC_Click(object senderEventArgs e)
{
    //対象を16進バイト列化
    byte[] data = Encoding.UTF8.GetBytes(txtOriginal.Text);

    //暗号用のキー情報をセットする
    byte[] desKey = Encoding.UTF8.GetBytes(key);
    byte[] desIV = Encoding.UTF8.GetBytes(vec);

    //暗号化オブジェクトとストリームを作成する
    using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(mstdes.CreateEncryptor(desKeydesIV),
                                       CryptoStreamMode.Write))
    {
        // ストリームに暗号化するデータを出力
        cs.Write(data0data.Length);
        cs.Close();

        // 暗号化されたデータを取得
        string code = byte2HexString(ms.ToArray());
        txtHash.Text = code;

        ms.Close();
    }
}

/// <summary>
/// 3DES複合化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn3DESD_Click(object senderEventArgs e)
{
    //対象を16進バイト列化
    byte[] data = hexString2Byte(txtHash.Text);

    //暗号用のキー情報をセットする
    byte[] desKey = Encoding.UTF8.GetBytes(key);
    byte[] desIV = Encoding.UTF8.GetBytes(vec);

    //暗号化オブジェクトとストリームを作成する
    using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(mstdes.CreateDecryptor(desKeydesIV),
                                       CryptoStreamMode.Write))
    {
        // ストリームに複合化するデータを出力
        cs.Write(data0data.Length);
        cs.Close();

        // 複合化されたデータを取得
        string code = Encoding.UTF8.GetString(ms.ToArray());
        txtRestre.Text = code;

        ms.Close();
    }
}


■文字列・バイト列操作の共通メソッド
/// <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 件のコメント: