電子書籍の厳選無料作品が豊富!

プログラミング・数学? 初心者です。

IDやパスワード管理によく出てくる一次方向(ハッシュ)関数ですが、
よくパスワードとSALTを一緒にしてハッシュ関数を通してハッシュ値を取得しますよね。
そしてその結果(データベースなどに記録済み)とログイン時に入力した値とを照らし合わせるわけですが、

昔まだ若いころ、これとは別のタイプのハッシュ関数を使用したことがあります。
それはある(パスワードなどの)値をハッシュ関数で処理すると「いろんなハッシュ値」が生成され、
そのハッシュ値から当然パスワードは予測できないのですが、
しかしその複数のハッシュ値は全て、そのパスワードから生成されたハッシュ値だということは分かる、という関数を使用したことがあります。

その時はperlのcpanモジュール(名前を覚えていません。すいません。)を使ったのですが、この別のタイプのハッシュ関数はどういう仕組みで作られているのでしょうか?
SALTが複数あり、そのそれぞれについて照合している?だけでしょうか?

それとも私が無知で、そんな関数がそもそも存在するだけでしょうか?

わかりません。教えてください。

A 回答 (2件)

crypt関数のようにパスワードの生成を目的とした関数でダイジェスト (質問者が言うところのハッシュ値) を作る場合、普通ダイジェストにはSALTの値が含まれています。


例えば、Perl標準のcrypt関数は、SALTとしてダイジェストを渡すとそこからSALTを自動的に取り出して、与えられたパスワードと本のダイジェスト生成時に使ったSALTを使ったダイジェストを計算します。
http://perldoc.perl.org/functions/crypt.html

よって、Perlのcrypt関数を使ったパスワードの検証は次のようにすると上記マニュアルでも説明されています。
| crypt($plain, $digest) eq $digest

質問者が言うところのCPANのモジュールはこれをラップしたようなモジュールだと予想します。
つまり、ハッシュ値を計算する関数を呼ぶと乱数などから自動的にSALTを作成し、ハッシュ値を返す。正しいパスワードか検証する関数は、ダイジェストと一緒に渡すと勝手にSALTを取り出して計算して一致、不一致を教えてくれるという動きをするのでしょう。
実際にコードで書くとこんな感じでしょうか。 (SALTが短く選び方も雑ですが、分かりやすさを重視してそこら辺は手抜きしてます)
sub my_crypt {
my ($password) = @_;
my @salt_candidate_chars = ('a' .. 'z', 'A' .. 'Z', '0' .. '9');
my $salt = $salt_candidate_chars[int(rand($#salt_candidate_chars + 1))].
$salt_candidate_chars[int(rand($#salt_candidate_chars + 1))];
return crypt($password, $salt);
}

sub my_verify {
my ($password, $digest) = @_;
return crypt($password, $digest) eq $digest;
}

my $d = &my_crypt("password");
print "digest: $d\n";
print "wrong:" . &my_verify("wrong", $d) . "\n";
print "correct:" . &my_verify("password", $d) . "\n";

> その時はperlのcpanモジュール(名前を覚えていません。すいません。)を使ったのですが、この別のタイプのハッシュ関数はどういう仕組みで作られているのでしょうか?

ランダムにSALTを生成する上記のような仕組みだと思います。

> SALTが複数あり、そのそれぞれについて照合している?だけでしょうか?

SALTが複数あるというより、上記のようにランダムに作っていると予想します。
そして、SALTがハッシュ値 (というか、ダイジェスト) と一緒に出力されていると思います。

当然、検証の時はダイジェストも渡しますよね?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。昔の事なので、今となっては曖昧な記憶しかありませんが、たぶんhanabutakoさんの言うとおりだと思います。ありがとうございます。

お礼日時:2013/08/05 00:08

crypt関数のことだと思うので、詳しいことは参照URLの閲覧をお願いします。



ランダムに生成されたsaltキーに関しては、生成されたハッシュ文字列に含まれるので、

1.保存されているハッシュ文字列からsaltキーを抜き出す。

2.入力されたパスワードとsaltキーを使って暗号化

3.暗号化したものと保存されているハッシュ文字列が合っているかを検証

4.認証

という手順です。

ちなみになぜsaltを使うのかというと、同じパスワードを設定していたとして一つがバレても、saltキーが違うおかげで生成されたハッシュ文字列が違うので、同じパスワードと気づかれないようにするのが大きな目的です。(他にもありますが。)

参考URL:http://www.sea-bird.org/doc/Solaris8/Perl_5.html
    • good
    • 0
この回答へのお礼

回答ありがとうございます。勉強になりました。

お礼日時:2013/08/05 00:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!