Perlモジュールで暗号化 - Crypt::RC4編
可逆式の暗号方式で、ストリーム暗号の代表格である「RC4」を紹介しておきます。
RC4は1987年に開発されたストリーム暗号であり、WEP(無線LANの標準仕様)やWinny(ファイル共有ソフト)、SSLやSSH等、広く利用されている暗号化方式です。
特徴として、DESと比較して高速であり、鍵の長さをある程度任意に設定できる点も挙げられています。
特徴として、DESと比較して高速であり、鍵の長さをある程度任意に設定できる点も挙げられています。
10-1. デモ
Crypt::RC4のデモです。文字列をRC4形式に変換します。
10-2. Crypt::RC4モジュール
Crypt::RC4モジュールは、PerlでRC4暗号アルゴリズムを利用するためのものです。
モジュールファイルが非常にシンプルにできており、扱いやすいという特性があります。 しかしその反面、hex/Base64出力のための関数などが用意されておらず、RC4モジュールを使った暗号/復号を補完する処理を作りこむ必要があります。
モジュールファイルが非常にシンプルにできており、扱いやすいという特性があります。 しかしその反面、hex/Base64出力のための関数などが用意されておらず、RC4モジュールを使った暗号/復号を補完する処理を作りこむ必要があります。
基本構文は次のとおりです。
| 関数形式 |
use Crypt::RC4; $encrypted = RC4( $passphrase, $plaintext ); $decrypt = RC4( $passphrase, $encrypted ); |
|---|---|
| OO形式 |
use Crypt::RC4; $ref = Crypt::RC4->new( $passphrase ); $encrypted = $ref->RC4( $plaintext ); |
ちなみに、Crypt::RC4は標準モジュールではないため、個別にインストールする必要があります。
ご参考 :
【コラム】Perlモジュールの組み込み
ご参考 :
【コラム】Perlモジュールの組み込み
10-3. 暗号と復号
暗号化のコードを考える場合、Crypt::RC4モジュールは、バイナリをテキストへ変換するためのhex/Base64変換の関数が用意されていないため、自前で作成する必要があります。
hex形式を扱う場合には、Perlでは、pack/unpack関数を使用します。
構文は次のとおりです。
それから、もう一点注意することがあります。RC4 + hex変換した場合に16進文字列の中に「改行」が混じることがあります。
改行を含む文字列をそのまま保管するのは扱いにくいため、この場合は改行を「n」に置き換えておくことにします(16進数の場合、nは使用しない)。
| 方式 | 構文 | 内容 |
|---|---|---|
| 16進文字列→バイナリ文字列 | pack('H2', text) | textという16進文字列をバイナリ文字列へ変換して返す |
| バイナリ文字列→16進文字列 | unpack('H2', bin) | binというバイナリ文字列を16進文字列へ変換して返す |
改行を含む文字列をそのまま保管するのは扱いにくいため、この場合は改行を「n」に置き換えておくことにします(16進数の場合、nは使用しない)。
use strict;
# モジュールを宣言
use Crypt::RC4;
# パスワード
my $passwd = '春はあけぼの';
# 秘密鍵
my $key = '清少納言';
# RC4暗号変換
my $crypt = RC4($key, $passwd);
# hex処理
$crypt =~ s/(.)/unpack('H2', $1)/eg;
$crypt =~ s/\n/n/g;
# 出力
print "$crypt\n";
> 8883f2eb71762aa08868fa6a
次に、復号方法(hex形式)は次のとおりです。
use strict;
# モジュールを宣言
use Crypt::RC4;
# 暗号文字
my $crypt = '8883f2eb71762aa08868fa6a';
# 秘密鍵
my $key = '清少納言';
# 16進をバイナリへ戻す
$crypt =~ s/n/\n/g;
$crypt =~ s/([0-9A-Fa-f]{2})/pack('H2', $1)/eg;
# RC4復号
my $plain = RC4($key, $crypt);
print "$plain\n";
> 春はあけぼの
暗号/復号のためのコード(hex形式)を1つにまとめてみましょう。
use strict;
# モジュールを宣言
use Crypt::RC4;
# パスワード
my $passwd = '春はあけぼの';
# 秘密鍵
my $key = '清少納言';
# RC4暗号
my $crypt = &encrypt($key, $passwd);
print "$crypt\n";
# RC4復号
my $plain = &decrypt($key, $crypt);
print "$plain\n";
#-----------------------------------------------------------
# RC4暗号
#-----------------------------------------------------------
sub encrypt {
my ($key, $plain) = @_;
# RC4暗号変換
my $crypt = RC4($key, $plain);
# バイナリを16進へ
$crypt =~ s/(.)/unpack('H2', $1)/eg;
$crypt =~ s/\n/n/g;
# 出力
return $crypt;
}
#-----------------------------------------------------------
# RC4復号
#-----------------------------------------------------------
sub decrypt {
my ($key, $crypt) = @_;
# バイナリへ戻す
$crypt =~ s/n/\n/g;
$crypt =~ s/([0-9A-Fa-f]{2})/pack('H2', $1)/eg;
# RC4暗号変換
return RC4($key, $crypt);
}
> 8883f2eb71762aa08868fa6a > 春はあけぼの
10-4. Base64形式の場合
Base64形式でのコードも考えてみます。
Base64に変換するには、標準モジュールであるMIME::Base64モジュールを使用します。
今回MIME::Base64モジュールの使い方で注意するところは、 encode_base64()関数のところで、デフォルトでは「改行」を含んだ複数の文字列に分割した値を返すため、オプションで改行を含まない1行の文字列を返すように指定します。
その場合、2番目の引数として以下のように空白の文字列を渡します。
Base64に変換するには、標準モジュールであるMIME::Base64モジュールを使用します。
| 概要 |
use MIME::Base64;
$encoded = encode_base64('Aladdin:open sesame');
$decoded = decode_base64($encoded);
|
|---|
その場合、2番目の引数として以下のように空白の文字列を渡します。
encode_base64($str, '')
このことを意識しながら、Base64出力での暗号化のコード例を記述してみます。
hex形式よりコンパクトに書けました。
hex形式よりコンパクトに書けました。
use strict; # モジュールを宣言 use Crypt::RC4; use MIME::Base64; # パスワード my $passwd = '明日デート決行'; # 秘密鍵 my $key = '極秘'; # RC4暗号 my $crypt = encode_base64(RC4($key, $passwd), ''); print "$crypt\n"; # RC4復号 print RC4($key, decode_base64($crypt)), "\n";
> hLOjHFIba2e2xwiJhHE= > 明日デート決行
Cryptography in Perl

powered by
Profile

