• ベストアンサー

ストレッチング

こんにちは。 今日、パスワードに関する記事を読みました。 パスワードというのは平文で保存しないで、代わりにハッシュ関数を施した値を保存して、これらの値が漏えいしても元のパスワードが解読されないようにしているみたいです。そして「ストレッチング」というのは、このハッシュ計算を何回も施した値を保存するのだそうです。 そこで、質問です: パスワードの保護に関して「十分に安全なハッシュ計算」(そういうモノがあるとして)の冪乗は、再び「十分に安全なハッシュ計算」になるのでしょうか。 よろしくお願いします。

  • jmh
  • お礼率34% (8/23)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

再び#1です。 私は文学部出身の人間で数式には滅法弱いので、私が理解できた範囲について補足させて頂きます。 > 元々パスワードの代わりにハッシュ値を保存すると、正しいパスワードとは異なる値を入力しても解錠してしまうという危険がありますが、それが増大したり…などで、安全性が低下したり(ほとんど役立たずになったり)することはないのか、突破に要する計算量の理論上の下限という意味では弱くなっていることもあるのではないか、という疑問です。 たとえば、参考に挙げて頂いたURLのように、f^10,000(x)の結果をyとして保存した場合、任意の入力値xについてf^n(x)を計算した結果、偶然yという出力を得る(= 衝突が発生する)可能性は確かにありますし、nが増加すれば増加するほどn回未満の試行で衝突が発生する可能性は確かに高くなります。 しかし、仮に10,000未満のn回目で衝突が発生するようなxを発見できたとしても、パスワードを保存しているサーバはプログラムに従って必ず10,000回計算を行います。このため、正確にnが10,000の時にyとなるxを求めないことには、攻撃に成功した(= パスワードを突破した)ことになりません。n回未満のどこかではなく、正確にn回目で衝突が発生するような、本来のxとは異なるxが出現する可能性は、nが増加すればするほど低くなるはずです。 また、仮に将来的に任意のyに対応するxを求める方法が発見されたとしても(現在利用されているハッシュアルゴリズムでそのようなものはありませんが)、nが増加すればするほど攻撃に要する時間も増加するので、安全性は高まっているといえるのではないでしょうか。なお、 > もし、弱くならない(or 強くなる)のであれば、f, f^2, f^3, …と無数に安全な(or より安全な)ハッシュ関数が得られてしまうというのが最初の違和感がでした。 ですが、nが大きくなればなるほど安全になるのが事実だとしても、計算にかけられる時間は有限なので、実際の実装は要求される安全性と処理時間とのトレードオフになります。たとえば、オンラインバンキングのパスワードを格納するのであれば、n = 10,000とするのも非現実的ではありませんが、流出して困るような情報が一歳存在しない社内の検証サーバのnを10,000に設定するのは、守るべき情報の価値を考えると過剰といえるでしょう。 参考 : ハッシュの衝突耐性について http://ja.wikipedia.org/wiki/MD5#.E3.83.8F.E3.83.83.E3.82.B7.E3.83.A5.E3.81.AE.E8.A1.9D.E7.AA.81.E8.80.90.E6.80.A7.E3.81.AB.E3.81.A4.E3.81.84.E3.81.A6

jmh
質問者

補足

> ですが、nが大きくなればなるほど安全になるのが事実だとしても、計算にかけられる時間は有限なので、 > いいえ。jmh は「再び十分に安全ですか」と疑いを持っています。逆に「nが大きくなればなるほど脆弱になっていくのではないですか」と質問しています。

その他の回答 (2)

回答No.2

こんにちわ、#1です。 > つまり、ストレッチングに関しての「安全」という言葉の意味は単に「fの逆計算表は既に知られていても、f^n の逆関数は未だだから」ということでしょうか? f = ユーザがパスワードとして設定する文字列の長さの方が、f^n = fをハッシュ関数にかけた結果として得られる文字列よりも圧倒的に短いということはお分かりかと思います。極端な話、f^n以上の長さの文字列を要求するシステムが仮に存在したとすれば、"fの逆計算表はすでに知られている"という前提が覆されますし、f^nすると逆に脆弱になってしまいます。 なお、ストレッチングの方法としては、ランダムなsaltと呼ばれる文字列(本文最後のURLをご覧ください)をユーザが設定した文字列に追加してハッシュ化する方法の方がメジャーです。 なので、ストレッチングに関しての「安全」という言葉が意味するところは、"ユーザが設定したオリジナルのパスワードの文字列を意図的に長くする(引き延ばす)ことにより、逆計算表を利用できなく(もしくは、総当たり攻撃を著しく困難 = 事実上不可能に)なるため、安全である"ということだと個人的に思います。 #stretch = "引き延ばす"という意味の動詞ですし。 余談ですが、f^nの逆計算表が作成されるほどにコンピュータが進化したら、より長いハッシュを出力するハッシュ関数が利用されるようになるでしょう(つまり永遠のいたちごっこです)。 ソルトについての解説 : http://ja.wikipedia.org/wiki/%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%AF%E3%83%A9%E3%83%83%E3%82%AF#.E3.82.BD.E3.83.AB.E3.83.88

jmh
質問者

お礼

しばらく、お休みしてました。申し訳ないです。 しかし少し疑問が解けたような気がします。今日、wikipedia の「暗号学的ハッシュ関数」を読み直したら、 > > 暗号学的ハッシュ関数は『既知』の全暗号攻撃法に耐性がなければならない。 > 少なくとも、… > とありました (『』は jmh)。何度も読んだハズなのに気付かなかったです。「既知の」とハッキリ書いてありました 。 http://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%AD%A6%E7%9A%84%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0 「原像計算困難性」「第2原像計算困難性」「衝突困難性」の「困難性」というのは、これらの「既知の攻撃方法」による困難性を指していて、未知の攻撃方法への耐性はそもそも評価していなかったようです。wikipedia には > > 計算複雑性理論では「困難 (hard)」という用語は特定の意味を持つ。 > しかしここでいう「困難」は、それとはほとんど関係がない。 > とあって、"ここでいう「困難」" が分からない…と思っていましたが、直前に書いてあったのです。 ストレッチングに対する攻撃手法は「それを再計算する以外は知られていない」のだから、元のハッシュ関数よりもずっと強いという結論になるのだと思います。

jmh
質問者

補足

ありがとうございます。自分自身の質問の意味がだんだんハッキリしてきたような気がします。申し訳ないです。 > f = ユーザがパスワードとして設定する文字列の長さの方が、f^n = fを > ハッシュ関数にかけた結果として得られる文字列よりも圧倒的に短いということは > お分かりかと思います。… > いいえ。2つのハッシュ計算法fとf^n とを比較していますので、fとf^n への「入力」は同じ「平文のパスワード(または+ソルト)」です。 y = f(x) ← xの代わりにyを保存します。 y = f(f(x)) = (f^2)(x) ← xの代わりにyを保存します。 y = f(f(f(x))) = (f^3)(x) ← … … y = f(f(…f(x))…) = (f^n)(x) ← 入力はいつもxです。 例えば、f(x) = (2 * x) % 16 =「入力値を2倍して16で割った余り」とすると、fの出力から入力を求めるには少しの計算が必要ですが、f^4 は定数関数=0なので全く計算する必要がありません。つまりf^4 の方が少し危険に見えます。元々パスワードの代わりにハッシュ値を保存すると、正しいパスワードとは異なる値を入力しても解錠してしまうという危険がありますが、それが増大したり…などで、安全性が低下したり(ほとんど役立たずになったり)することはないのか、突破に要する計算量の理論上の下限という意味では弱くなっていることもあるのではないか、という疑問です。もし、弱くならない(or 強くなる)のであれば、f, f^2, f^3, …と無数に安全な(or より安全な)ハッシュ関数が得られてしまうというのが最初の違和感がでした。 ちなみに、読んだのはこれだったようです: http://blog.tokumaru.org/2013/08/1.html

回答No.1

こんにちわ。 要するに、"パスワードの文字列をハッシュ関数にかけた結果"と、"その値を更にハッシュ関数にかけた結果"について、安全性に違いがあるかどうかという質問ですよね。 ご存知の通り、任意のハッシュ文字列αから元の文字列を推測することは基本的に不可能です。 強引に推測する場合、元の文字列となりうる文字列を片っ端からハッシュ関数にかけて、その結果がαになるまで施行を繰り返すブルートフォース攻撃を行うことになりますが、これは攻撃の効率が非常に悪い攻撃になります(莫大な時間と計算量を要する)。 それならば、予め任意の文字列をハッシュ関数にかけた結果をデータベースとして保持しておき、必要なときはそのデータベースを検索すればいいじゃないか、という攻撃方法が考案されました。そのデータベースを"レインボーテーブル"と呼びます。ちなみに、個人レベルでレインボーテーブルを作成するのは不可能に近いので、それを利用したい場合は膨大な計算リソースを持つ誰かが計算した結果を利用することになります。 参考URLを見て頂ければ分かりますが、実はレインボーテーブルは比較的容易に入手できてしまいます。しかし、対象となる文字列の長さはたかが知れており、参考URLの例では最大10文字となっています(それ以上は作成自体 or ファイルサイズが現実的ではなくなる)。政府クラスの膨大な計算リソースを持った組織が本気になればもう少し文字数は増えるでしょうが、桁が増えることに指数関数的に計算量が飛躍的に増加するため、せいぜい数文字増える程度でしょう。 ここで最初に戻りますが、"パスワードの文字列をハッシュ関数にかけた結果(のハッシュ文字列)"は、パスワードが10文字以下であれば誰でも入手可能なインボーテーブルに載っているので、多少の心得がある人の手にかかればすぐに解読できてしまいます。しかし、"その値を更にハッシュ関数にかけた結果"は、入力される文字列が現在は脆弱とされあまり利用されなくなったMD5でさえ32文字、SHA1であれば40文字にもなるため、レインボーテーブルを利用して解読するのは世界中の誰にも当分不可能でしょう。 結論として、"一度ハッシュ関数にかけた結果を入力文字列とすることは、入力文字列を飛躍的に長くすることを意味するため、レインボーテーブルを利用したクラッキングが事実上不可能になる"という効果があるといえるでしょう。

参考URL:
http://project-rainbowcrack.com/table.htm
jmh
質問者

補足

ありがとうございます。 > 要するに、"パスワードの文字列をハッシュ関数にかけた結果"と、 > "その値を更にハッシュ関数にかけた結果"について、安全性に違いが > あるかどうかという質問ですよね。 > はい。ハッシュ関数fのn乗「f^n」(n≧1)同士を比較しています。 例えば…、 1. 異なる入力に対して同一の出力を得てしまう可能性は、元のハッシュ関数fよりもf^2、f^3、f^4、…の方が(この順で)高くなっていくように感じます。 2. 36度の回転行列の逆行列を求めるよりも、その10乗の逆行列を計算する方が直感的には簡単に思えます。ハッシュ関数の冪乗は必ず逆算が困難なのでしょうか。 …というようなことでした。 > 予め任意の文字列をハッシュ関数にかけた結果をデータベースとして保持しておき、 > つまり、ストレッチングに関しての「安全」という言葉の意味は単に「fの逆計算表は既に知られていても、f^n の逆関数は未だだから」ということでしょうか?

関連するQ&A

  • ユーザーパスワードのDBの格納について

    あるメーカーのソフトウェアを使用しており、Webからログインするときのユーザ名、パスワードがユーザーデータベースのテーブルに平文で格納されています。 そのソフトで使用しているデータベースはSQL Server 2008R2になります。 平文で格納されているのが気になっており、SQL Server 2008R2を使用してテーブルに格納するパスワードをハッシュ+ソルト+ストレッチングして格納すること仕組みとして可能かどうか気になっております。 もし仕組みとして可能な場合、Webからログインした際にユーザーが入力したパスワードをハッシュ+ソルト+ストレッチングして、テーブルに格納されているハッシュ+ソルト+ストレッチングしたパスワードと比較して認証を行うようにプログラミングは可能でしょうか。

  • 金融機関ではパスワードは平文管理ですか?

    ある証券会社でパスワードが分からなくなったため、通知の依頼をしたところ、教えて貰えました。 ただ、振り返って考えてみると、書留ではありましたが、登録したことのあるパスワードがそのまま届きました。 金融機関では、ハッキングなどセキュリティを高める目的でパスワードはハッシュで格納してあり、パスワードそのものは保存していないと思っていたのですが違うのでしょうか? 一般に金融機関ではハッシュではなく平文で保存されているのでしょうか?

  • PHP PEAR AUTH 認証でのパスワードを忘れた場合

    AUTHを利用しての、認証を行う場合、usernameとpasswordの カラムを持つテーブルを参照しますが、このpasswordは MD5でハッシュした値で、テーブルに格納しなければならないようです。 この場合、パスワードを忘れてしまった際など、テーブルを 見てすぐにpasswordの値が確認できないので不便です。 なのでテーブルに格納するパスワードは平文としたいと思います。 平文でpasswordを格納しても、'cryptType'=>"none"とすれば 認証は通りますが、やはり平文では心配な所があります。 良い解決方法があれば教えてください。

    • ベストアンサー
    • PHP
  • POP3 over SSL と APOPを併用した方がよいか

    お世話になります。 APOPの脆弱性は、MD5やSHA-1のハッシュの問題と合わせて色々と難しい理屈のようですが、私の場合はPOP3S(POP3 over SSL)でメールサーバーと通信しているため、IDとパスワードは暗号化されています。 そこで思ったのですが、この暗号化はそれなりに強力な物だとは思っていますが、このSSL接続の中でさらにAPOPを使った方がすこしは安全性がマシになる、といった事はあるのでしょうか。 普通はPOP3を使用すると思いますが、もしSSL接続の中身が見られたとき、APOPならさらにこれを解読(?)する必要がありますよね。 しかし、一般のSSLを破るほどならAPOPなんて数秒で解読できる意味のない物なのでしょうか。 メーラーでかんたんに選べる設定だけに、無意味に悩んでいます。 平文で送るのとAPOPで送るのと (どちらも、それをさらにSSLで送るわけですが)どちらがよいのでしょうか? もちろんメール本文はどちらにしろサーバーの先で平文になりますよね、それは分かっています。 理解が間違っていたらご指摘ください。

  • Yahoo! ユーザ・パスワード流出について

    ユーザ ID だけではなく、1 百万超ユーザのパスワードが漏れていたらしいことを発表しましたが、 これはパスワードのいわゆるハッシュ・リストなのでしょうか。それ以上のことが書かれていないので、何ともわかりません。 それとも、平文のリストでも存在して、それが流出したのでしょうか。 前者の場合は辞書攻撃や総当たりの「事務的」手続きが簡略化されるだけで、さして問題とならないような気がしますが、万一後者なら、なぜそんなリストが存在するのでしょうか。 スーパユーザが一般ユーザのパスワードを知る必要なんてどこにも存在しない(SU は何でもできるので)と思いますが、管理者がそんなものを保存する意義は何かあるのでしょうか。

  • パスワードの決め方について(SHA3orHMAC)

    パスワードの決め方や保管の方法について、分からなくなってきたので基本から質問させてください。 1.パスワードをホームページ等でネットに公開したら危険ですか? 2.1.はただそのまま公開したら危険なのでやってはいけないと思いますが、暗号化して、パスワードのパスワードがないと解けない状態にして公開しておけば安全ですか? 3.2.の暗号化の手法として、暗号学的ハッシュ関数を用いて、ハッシュ値 h をパスワードにすれば、暗号化したパスワードを公開しても安全ですか? 4.3.について、パスワードにしたハッシュ値 h を公開したのではパスワードをそのまま公開していることになり、危険なため、ハッシュ値 h を算出する暗号学的ハッシュ関数の実行コマンドをホームページ等で公開し、パスワードを確認したいときにはこのコマンドを実行してハッシュ値を得ることにすれば、安全ですか? 5.4.について、暗号学的ハッシュ関数はSHAシリーズなどがありますが、この実行コマンドは広く一般に利用できる状態で提供されているため(ハッシュ計算するソフトウェアやWebサイトなど)、SHAなど既存の暗号学的ハッシュ関数を用いるのではなく、自分で専用に暗号学的ハッシュ関数を考案し、また実行コマンドやソフトウェアを作成する必要がありますか? 6.5.が大変な場合、SHAなど既存の暗号学的ハッシュ関数を用いて4.を実現するにはどうしたらいいですか? 7.4.について、コマンドがパスワードの数だけ存在すると管理が大変です。コマンドは共通にして、オプションスイッチで区別することはできませんか? 8.7.について、コマンドは既存のソフトウェアをあらかじめインストールしておき、オプションスイッチを含む実行コマンド文のみをHP等で公開しておくことはできませんか? 9.6.7.8を実現するには、オプションスイッチのうちのひとつをパスワードのパスワードとして、このスイッチのみを非公開とすれば良いですか? 10.9.について、コマンド文はどのように記述すれば良いですか?たとえばハッシュ関数H()、出力h、パスワードの対となる文字列(IDとかファイル名等)m、パスワードのパスワードをk、||は結合とした場合、 H(k||m)=h と書けると思いますがこれをH(m)として公開し、kはあらかじめPC等コマンドを実行する環境で設定しておけば良いですか? 11.10について、暗号学的ハッシュ関数SHA2シリーズ(256bit等)を用いた場合、Merkle-Damgård 構造であるため、length-extension 攻撃され、危険ですか? 12.10.11.について、暗号学的ハッシュ関数SHA3シリーズを用いた場合、SHA2シリーズのハッシュ関数と異なりスポンジ構造であるため、length-extension 攻撃は成り立たず、安全ですか? 13.12について、length-extension 攻撃以外の危険性はありますか?

  • 私の理解度の確認の為に、此の質問を致します。

    パスワード生成器で作られた暫定的なパスワードの値が、 たとえ不正なサーバへのログインによって聴取されましても、 もし元のパスワードが漏洩されていませんでしたら、 其の不正なサーバの管理者がNTPサーバで時計合わせを試みたところで、 更新後のパスワードと同じ値の生成は殆ど為され得ませんね。 従いまして、其の故に、 トークン由来のパスワードは(チャレンジへのレスポンスの場合よりも)安全に個人情報を守れるのでしょうか?

  • メーラーとパスワード

    メーラーでメールサーバーに送信するパスワードは安全かどうかという質問です。 例えばYahooメールではセキュアモードによるログインが可能で、この時入力するパスワードはSSLで保護されており安全だと思うのですが、YahooメールをOEなどで受信する場合、OEから送信するパスワードはセキュアモードで処理されるのでしょうか? もしかしてパスワードを平文で送信しているのでは?と思ってしまいます。 Yahooメールに限らず、メーラーで送受信できるフリーメールや他の接続プロパイダが提供するメールについても同様の疑問を持っています。 なんだか初歩的な質問ですが、分かる方回答宜しくお願いします。

  • base64後、1文字ずつ暗号化すると解読困難?

    計算コストを幾分度外視して考えると、通常の業務連絡的な内容のメールであれば、 base64を通してから1文字ずつパスワード付きでハッシュ関数に通せば パスワードがばれない限りかなり解読困難ですか? (2文字目からは暗号化後の1文字目もつける→3文字目は2文字目・・・以下末尾文字まで) またどの程度実用的でしょうか。(用途はどの程度限定されるでしょうか。) メールにGmailなどの無料Webメールしか使っていないので なるべく長持ちする暗号化として考えてみました。 回答お願いします。

  • N個の数字を使って表せる最大の数

    計算記号を使わないで1、2、3、4 を一回ずつ使って、できるだけ大きい数を表すにはどうしたらよいでしょうか? ただし右肩に乗せた累乗を表す図を描く代わりに、べき乗記号 ^ を使うのはかまいません。また^は何個使っても結構です。 というクイズを出されました。 2^3^41、3^4^21、4^3^21の3つまで候補をしぼったのですが、値を検証しようとしたところ関数電卓でオーバーフローとなりどれが最大なのか分かりませんでした。 どうしたら最大値をみつけることができるでしょうか? 同様に1234567890を一回ずつ使ってできる最大の数は何でしょうか? 一般にN個の数字を使って、できるだけ大きい数を見つけるにはどうすればよいでしょうか?