Crypt::OpenSSL::RSA
RSA暗号・電子署名アルゴリズムを実行するOpenSSLラッパモジュール。
use Crypt::OpenSSL::RSA;
パッケージをロードする。
my $rsa = Crypt::OpenSSL::RSA->generate_key($size);
鍵のbitサイズを指定して鍵を生成し、インスタンスを作成する。
my $rsa = Crypt::OpenSSL::RSA->new_public_key($key_string);
Base64/DERエンコードされたPKCS#1またはX.509表記の公開鍵を入力してインスタンスを生成する。
my $rsa = Crypt::OpenSSL::RSA->new_private_key($key_string);
Base64/DERエンコードされたPKCS#1表記の秘密鍵を入力してインスタンスを生成する。
my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p,
$q);
鍵パラメタの実値を入力してインスタンスを生成する。各鍵パラメタは、Crypt::OpenSSL::Bignum
オブジェクトを入力すること。暗号化・署名検証しか実行しないのであれば、秘密鍵パラメタ d, p, q は省略可。
my $encrypted = $rsa->encrypt($plain);
暗号化を実行する。平文サイズの制限は下記の通り。
PKCS#1 padding:鍵長-11バイト以下
OAEP padding:鍵長-42バイト以下
paddingなし:鍵長と同じ(「以下」ではない)
my $plain = $rsa->decrypt($encrypted);
復号を実行する。暗号文サイズは鍵長と一致していなければならない。
my $signature = $rsa->sign($text);
入力データに対する電子署名を生成する。デフォルトのハッシュ関数はSHA-1。use_sha256_hash()
メソッドなどを使って変更することも出来る。
my $result = $rsa->verify($text, $signature);
署名検証を行なう。
$rsa->use_pkcs1_padding();
PKCS#1 v1.5 paddingを指定する。デフォルト。
$rsa->use_oaep_padding();
PKCS#1 v2.0 で追加されたOAEP paddingを指定する。padding
$rsa->use_no_padding();
paddingを実行しない。モジュール外部で適切なpaddingを行なって入力する場合に使用する。
my $public = $rsa->get_public_key_string();
DER/Base64エンコードして公開鍵を出力する。
my $public = $rsa->get_public_key_x509_string();
X.509/Base64エンコードして公開鍵を出力する。
my $private = $rsa->get_private_key_string();
DER/Base64エンコードして秘密鍵を出力する。
my ($n, $e, $d, $p, $q) = $rsa->get_key_parameters();
鍵パラメタの実値を取得する。各鍵パラメタは、Crypt::OpenSSL::Bignum
オブジェクトで出力される。
my $size = $rsa->size();
保持されている鍵のバイト長を返す。
Crypt::RSAなるモジュールもあるが、このモジュールには色々バクがあるので、Crypt::OpenSSL::RSA を使うこと。確認済みのバグは以下の通り。Active Perl では Crypt::OpenSSL::RSAはサポートされていないので、下記の箇所を修正してCrypt::RSAを使うしかない。
Crypt::RSA::Key::Private::check()
暗号化と署名検証は、公開鍵だけで実行できる(できないと困る)が、秘密鍵の整合性までチェックしてしまっているため、秘密鍵を持っていない状態だとエラーが発生して暗号化・署名検証を実行できない。
Crypt::RSA::Key::msg1()
MGF1関数の仕様が間違っている。
ループカウンタが +4 づつされていて、且つ、ループ回数が違う 。下記のソースが正解。
sub mgf1 {
my ($seed, $l) = @_;
my $hlen = 20; my ($T, $i) = ("",0);
for (0 .. ($l/$hlen)) {
my $C = i2osp (int($i), 4);
$T .= sha1("$seed$C");
++$i;
}
my ($output) = unpack "a$l", $T;
return $output;
}