みなさん、人に見られたくないデータのひとつやふたつあるのではないでしょうか。そこで今回は暗号化に挑戦することにします。C#ならファイルの暗号化も簡単にできてしまいます。

暗号には共通鍵暗号と公開鍵暗号があります。共通鍵暗号は対称鍵暗号とも呼ばれ、暗号化と復号に同一の(共通の)鍵を用いる暗号方式です。それに対して公開鍵暗号は暗号化と復号化のときには別の鍵を使います。今回扱うのは共通鍵暗号です。

共通鍵暗号にはストリーム暗号とブロック暗号があります。ビットやバイト単位で暗号化するのではなく、決まった長さのデータをブロックにして暗号化していきます。いまではブロック暗号の方が一般的です。

AES暗号

そのなかでも強力な暗号がAESです。AESはAdvanced Encryption Standardの略で、アメリカ国立標準技術研究所(NIST)の主導により公募され採用された暗号方式なのです。

AESの鍵長は3種類あり、128ビット、192ビット、256ビットのいずれかです。ブロック長は128ビットの1種類のみです。

暗号化のためにはAesManagedクラスを使います。そして暗号鍵と鍵のサイズ、暗号利用モードを決めます。暗号利用モードはECBとCBCがありますが、CBCが一般的で、ECBは非推奨です。

なぜか? 同じデータを同じ暗号鍵で暗号化した場合、同一の暗号パターンとなってしまうからです。文章の場合、決まり切った書き出しになっている場合、それが解読を試みる者にとってヒントになってしまうからです。

ところがCBCは同じデータを同じ暗号鍵で暗号化しても同一パターンにはなりません。ブロックごとに暗号化の処理をしていくのですが、そのときに1つ前の処理結果を利用します。初期化ベクトルを変えることで暗号化されたデータを変えることができるのです。

ブロックごとの処理において1つ前の処理結果を利用する。では一番最初はどうするのでしょうか。このときに使われる値が初期化ベクトルです。

また一定の長さのブロックごとに処理していくと最後のブロックの部分で余ったり足りない部分がでてきます。これを埋める方法として用意されているのがパディングです。

暗号化をするためには


鍵長
ブロック長
暗号利用モード
パディング
初期化ベクトル

これらを決める必要があります。

実際につくってみる

鍵長  256
ブロック長  128
暗号利用モード CBC

鍵はパスワードからつくることにします。Rfc2898DeriveBytesクラスを使うとパスワードから鍵を生成することができます。

Rfc2898DeriveBytesで鍵をつくるにはSaltが必要です。Saltは8バイト以上でなければなりません。そこでまずSaltを生成し、それを利用して暗号キーと初期化ベクトルを生成しています。復号化のときにSaltと初期化ベクトルが必要になるので暗号化されたファイルの先頭につけることにします。

暗号化をするまえに圧縮をしています。平文に冗長さがあるとそのまま暗号化しても解読されやすくなります。暗号化する前に圧縮することで、この問題を解決することができます。

あとはこれらのメソッドを呼び出すだけです。