巨大な暗号化されたファイルを複合化する方法

CGIテクニック集トップへ





概要

Blowfishアルゴリズムを使って巨大な暗号化されたファイルを元ファイルに複合化して保存します。 クリプトアップで使われています。 暗号化の方法は巨大なファイルを暗号化する方法を参照ください。

必用な処理

  1. Crypt::CBCモジュールを読み込む
  2. Crypt::CBCオブジェクトを作成する
  3. 復号化処理をスタートする
  4. 入力ファイルをオープンし、一定のブロックごとにファイルを読み込む
  5. そのブロックを復号化し、ファイルに書き出す
  6. 全てのファイルが終わるまで繰り返す
  7. 復号化の終了処理をする
  8. ファイルをクローズする

サンプルコード

 use Crypt::CBC;
 
 my $key = 'MySecretKey';
 
 my $cipher_options = {
        key            => "$key",
        cipher         => 'Blowfish',
        salt           => 1,
 };
 
 my $cipher = Crypt::CBC->new($cipher_options);
 
 my $infile = 'encrypted.dat';
 my $outfile = 'plain.dat'; 
 
 my $cipherblock = 1024 * 16 # 16KB
 
 open (ENCFILE, "< $infile");
 open (DECFILE, "> $outfile");
 binmode ENCFILE;
 binmode DECFILE;
 $cipher->start('decrypting');
 my $buffer;
 while (read(ENCFILE,$buffer,$cryptblock)) {
        print DECFILE $cipher->crypt($buffer);
 }
 print DECFILE $cipher->finish();
 close (DECFILE);
 close (ENCFILE);

コードの解説

 use Crypt::CBC;

Crypt::CBCを読み込みます。

 my $key = 'MySecretKey';
 
 my $cipher_options = {
        key            => "$key",
        cipher         => 'Blowfish',
        salt           => 1,
 };

Crypt::CBCのオブジェクトを作成するのにオプションを設定します。Crypt::CBCコンストラクタ(new)に渡すオプションはハッシュのリファレンスで作成します。 $keyに複合化のキーを設定します。MySecretKeyが復号化のキーになります。このキーは暗号化のキーと同じものでなければいけません。 chipherにCipherのモードを設定します。ここではBlowfishアルゴリズムを指定します。 slatを1に設定しているので実際のキーとInitialization Vectorを作成するsaltをランダムで作成します。実際のキーは入力されるキーからランダムに作成され、それによって暗号がされます。Initialization Vectorはオプション指定しないのでモジュールが自動的に作成し、暗号化された文字列に埋め込みます。 その他のオプションは指定する必要がないか、デフォルトものまま使います。 その他のオプションについてはhttp://search.cpan.org/~lds/Crypt-CBC-2.22/CBC.pmを参照ください。

 my $cipher = Crypt::CBC->new($cipher_options);

Crypt::CBCのオブジェクトを作成します。先に指定したハッシュのリファレンスを渡します。引数はハッシュのリファレンスなので、

 my %cipher_options = (
        key            => "$key",
        cipher         => 'Blowfish',
        salt           => 1,
 );
 
 my $cipher = Crypt::CBC->new(\%cipher_options);

このようにも記述できますし、

 my $cipher = Crypt::CBC->new({
        key            => "$key",
        cipher         => 'Blowfish',
        salt           => 1,
 });

このようにも記述できます。

 my $infile = 'encrypted.dat';
 my $outfile = 'plain.dat';

元ファイルと暗号化後のファイル名を指定します。

 my $cipherblock = 1024 * 16 # 16KB

一回で暗号化するサイズを指定します。ここでは、16KBにしています。この数字が大きければ、それなりにメモリーを使用しますし、小さければ、元ファイルのサイズに対して繰り返し量が多くなります。このサイズは暗号化した時と同じサイズにしなければいけません。

 open (ENCFILE, "< $infile");
 open (DECFILE, "> $outfile");

元ファイルと複合化後のファイルを開きます。

 binmode ENCFILE;
 binmode DECFILE;

元ファイル、復号化後のファイルハンドルのbinmodeを指定します。これがないと復号化ファイルが化けたり、元ファイルがバイナリだった場合に正常に動作しません。

 $cipher->start('decrypting');

復号化モードを指定します。このstartメソッドに指定する引数は、始まる文字列が'e'か'E'の場合には、暗号化モードになります。'd'か'D'で始まる文字列の場合には、複合化モードとなります。

 my $buffer;
 while (read(ENCFILE,$buffer,$cryptblock)) {

ファイルを$cryptblockのサイズ分だけ読み込み、全部が終わるまで繰り返します。

        print DECFILE $cipher->crypt($buffer);

ここでそのブロック分を暗号化してファイルに書き出します。

 }
 print DECFILE $cipher->finish();

繰り返しが終わったあとの最後にfinishメソッドが必要になります。これもファイルに書き出さないといけません。ここでメモリに残った最後の復号化文が処理され出力されます。

 close (DECFILE);
 close (ENCFILE);

ファイルをクローズします。

関連するCGIテクニック

テキストファイルを暗号化する方法
暗号化ファイルを元のテキストファイルに戻す方法
巨大なファイルを暗号化する方法