Landscape トップページ | < 前の日 2005-08-14 2005-08-16 次の日 2005-08-17 >

Landscape - エンジニアのメモ 2005-08-16

C# でファイルを暗号化・復号化する


* C# でファイルを暗号化・復号化する

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [.net] [C#]

MSDN を参考に C# で AES (Rijndeal) を使って暗号化・復号化するサンプルを書いた。

MSDN Online = 10 行シリーズ 〜 10 行でズバリ !! 暗号化 (C#) 〜
http://www.microsoft.com/japan/msdn/thisweek/10lines/encrypt ...

- .net には標準で AES などの暗号化ライブラリが用意されている

.net には標準で暗号化ライブラリが入ってるので、System.Security.Cryptography にあるクラスを使えば速攻で暗号化・復号化できる。とても楽だ。

RijndaelManaged メンバ
http://www.microsoft.com/japan/msdn/library/default.asp?url= ...


MSDN サンプルでは 3DES を使っていたが、私のサンプルコードでは AES を使った。3DES は遅いだろうから。結城さんの「暗号技術入門」にも以下のように書かれていたし。「今後使うなら、AES (Rijndeal) がよいでしょう。安全で高速、しかも幅広いプラットホームで利用できるからです。」

「暗号技術入門」は良い本だ。非常にわかりやすい。認証や暗号化の機能をシステムに組み込む必要があるけど、知識がないというエンジニアは必読。この本を読んだおかげで、IV (Initialization Vector - 初期化ベクタ) やブロック暗号モードの意味を知ることができた。

ただ、知ってるのとライブラリを使いこなせるというのは別の概念だ。事実、最初にライブラリのヘルプだけを見て書こうとしたら以下のようなエラーを出された。しょうがないので MSDN のサンプルを見たという次第。

System.Security.Cryptography.CryptographicException : 指定された Initialization Vector (IV) のサイズは、このアルゴリズムのブロック サイズと一致しません。

無理に自分で生成せずに、普通に RijndaelManaged.GenerateIV() メソッドを使えば良いのね。

- C# で AES を使って暗号化・復号化するサンプルコード

NUnit 向けのテストが入ってるけど、先頭行の [Test] と aes_encrypt_decrypt_sample() メソッドの Assert.AreEqual(str, decoded); を削除すれば問題なく動く。

using System.IO;
using System.Security.Cryptography;

private byte[] _key;
private byte[] _IV;

[Test]
public void aes_encrypt_decrypt_sample() {
    string str = @"対称アルゴリズムでの暗号化では、ストリームが利用されます。ストリームを利用することで、データ用の中間ストレージも必要とせず、様々なデータ アクセスの手法を提供します。また、対称アルゴリズム、ハッシュアルゴリズムで共通の CryptoStream を利用することで、より使いやすいインタフェースを提供します。";

    RijndaelManaged aes = new RijndaelManaged();
    aes.GenerateKey();
    aes.GenerateIV();
    _key = aes.Key;
    _IV = aes.IV;

    string encoded = encrypt(str);
    string decoded = decrypt(encoded);
    Assert.AreEqual(str, decoded);
}

/// <summary>
/// 文字列を暗号化
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private string encrypt(string str) {
    byte[] source = Encoding.Unicode.GetBytes(str);
    RijndaelManaged aes = new RijndaelManaged();
    byte[] destination;
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(_key, _IV), CryptoStreamMode.Write)) {
        cs.Write(source, 0, source.Length);
        cs.FlushFinalBlock();
        destination = ms.ToArray();
    }
    return Encoding.Unicode.GetString(destination);
}

/// <summary>
/// 文字列を復号化
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private string decrypt(string str) {
    byte[] source = Encoding.Unicode.GetBytes(str);
    RijndaelManaged aes = new RijndaelManaged();
    byte[] destination;
    using (MemoryStream ms = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(_key, _IV), CryptoStreamMode.Write)) {
        cs.Write(source, 0, source.Length);
        cs.FlushFinalBlock();
        destination = ms.ToArray();
    }
    return Encoding.Unicode.GetString(destination);
}

実際に使う場合は引数や戻り値はバイト配列の方がいいだろうけど、サンプルとして書きやすいので string にした。

すべての記事の見出し (全1029件)
全カテゴリの一覧と記事の数
カテゴリごとに記事をまとめ読みできます。記事の表題だけを見たい場合は、すべての記事の見出し (カテゴリ別表示) へ。

直近30日分の記事
2007-04-23 (Mon)
2007-03-07 (Wed)
2007-02-27 (Tue)
2007-01-17 (Wed)
2007-01-15 (Mon)
2007-01-14 (Sun)
2007-01-08 (Mon)
2006-12-01 (Fri)
2006-11-22 (Wed)
2006-11-20 (Mon)
2006-11-19 (Sun)
2006-09-30 (Sat)
2006-08-29 (Tue)
2006-08-04 (Fri)
2006-07-27 (Thu)
2006-07-23 (Sun)
2006-07-17 (Mon)
2006-07-10 (Mon)
2006-07-06 (Thu)
2006-07-03 (Mon)
2006-06-29 (Thu)
2006-06-28 (Wed)
2006-06-27 (Tue)
2006-06-25 (Sun)
2006-06-19 (Mon)
2006-06-18 (Sun)
2006-06-15 (Thu)
2006-06-11 (Sun)
2006-06-01 (Thu)
2006-05-30 (Tue)
プロファイル
斎藤 宏明。エンジニアです。宇都宮市に住んでいます。
リンク
RSS
スポンサードリンク
Powered by
さくらインターネット

© 斎藤 宏明 Saito Hiroaki Gmail Address
Landscape - エンジニアのメモ http://sonic64.com/
Landscape はランドスケープと読みます。
ひらがなだと らんどすけーぷ です。