• 締切済み

パスワードの最良な決め方について(長文)

パスワードを最大限に複雑に決めたいとします。 当然、覚えられないので、適当な言葉で決めて、seedを付けてハッシュ関数へ入力し、出力をそのままパスワードとして使うとします。 (ハッシュ関数の出力は16進数ですが、文字数を少なくしたいので、使える文字を全て使用して、文字へ割り当てます。) seedは秘匿し、適当な言葉にあたる部分はブログ等に公開でもいいからメモっておくとします。 例えば、この質問サイト(OKWaveからログインしてます)であれば、 OKWavePassword_change#_0 といったような言葉を決めて、SNSのプロフに載っけておくとかです。 実際に使う際には、頭に(どこでもいいのですが)seedを付けて、 myseedOKWavePassword_change#_0 のようにして、ハッシュ値を取り、文字割り当てしてクリップボードへコピーして パスワード欄に貼り付けるかんじです。 ここからが質問です。 【質問1.ハッシュ関数はどれを使えば良いでしょうか?】 SHA-2シリーズはlength-extension攻撃に弱いので、HMACの形式にして使わなければならず、またその場合、Windowsのコマンドプロンプトで使える手軽な実装が見つからないのもあって(コマンドプロンプトにこだわる訳は要望があれば補足で説明したいと思います)、使用は避けたいです。 そこで、SHA-3シリーズが策定されてるようなので、この中で最大のビット数のものを選べば良いと思っていたのですが、Wikipediaを見たら、SHAKE128、同256というのがあり、読んでみると、 出力長を、任意に設定できる そうですが、だとすると、SHA-3の最大ビット数(SHA-3 512)と比べて、上述の使い方で考えると、どちらが良いでしょうか? もしくは、他により良いハッシュ関数がありますか? というのは、SHA-3 512では(というか、SHAKE以外のSHA-3では)出力長は固定なので、必要であれば(ほぼ全てのケースだと思いますが) そのパスワードで使用できる最大文字数にしなければならず、 その方法としては、文字割り当てまで終わってから、ただ単に頭から文字数分取るとか、間の文字を抜いて詰めるくらいしか思いつかないので、 それでどの程度、一様性が下がって(偏りが生じて)、危険になるかは、良く分からないのですが、 それであれば、512ビットより落ちる256ビットであるとしても、SHAKEであれば、ハッシュ値が得られた時点で過不足の少ない(0にはならないみたいですが、実装のせい?)情報量に収まっているので扱いやすいこともあり、いいかなと思っているのですが、どうでしょうか? 要するに、512ビット固定長のハッシュ値を文字割り当てしてから(16進表現の時点では難しそうなので)、頭から一定の大きさまで削った場合と、 SHAKE256で最初から過不足の少ないハッシュ値を得て文字割り当てした場合とで、どちらがよりマシかということになると思いますが…… 例えば、例としてGmailのパスワードで考えると、確か、ASCII印字文字95種フルフルで使えて最長64文字だったと思いますが、 この場合だと512ビット固定長のがマシになりそうですが…… (512ビットを95進数表現すると78文字(桁)だから、78文字の先頭から文字を取るなり、間を詰めるなりして64文字にするほうが、256ビット分(95進数で39桁)を無理に引き伸ばすより安全そうというのが理由) ↑のようなパスワードを使うことが多ければ、というか多くなくても今後10年くらいは変えたくないので(SHA-1やSHA-2の寿命から;2はまだ死んでませんが)後々の事を考えればSHA-3 512で統一しておいたほうが結局無難でしょうか。 或いは、どっちもダメということもあるのでしょうか…… そもそも、ハッシュ関数を使うという考え方自体がダメだったりするのでしょうか…… 【質問2.仮にSHAKE256を使うとすると、出力長はどうやって求めれば良いでしょうか?】 例えば、OKWaveでは、パスワードの文字条件が、 使える文字がa~z, A~Z, 0~9, -, _で、文字数が最大10文字だそうですが、 この場合、パスワードの総パターン数を16進数で表した文字数にすればいいのでしょうか。 具体的には、総パターン数は64の10乗通りで1152921504606846976個、 16進数にすると1000000000000000で16文字で合ってますか? また、多くの実装では、出力値が0起算のため、例えば今の例だと実際に取り得る値は 0~((64の10乗)-1) の範囲になるかと思いますが、つまり、 000000000000000~FFFFFFFFFFFFFFF が実際に出てくる値の最小~最大となるため、15文字で設定すれば良いということでしょうか? 【質問3.具体的な例で確認したいのですが?】 SHAKE256で15文字として、seedはなしとすると、 OKWavePassword_change#_0 のハッシュ値は 911C7E7009C307 と出ましたが合ってますか。(HashSum使用←バイト単位でしか設定できないので、8byteだと文字割り当て後、11文字になるパターンが有り得るので7バイトで設定(1byteは16進数2文字)) またこれを64進数に変換すると、 02 17 07 07 57 48 02 28 12 07 になると思いますが合ってますか。 またこれを文字割り当て(ASCII文字コード表の通りの順番で、使用できる文字だけ拾って割り当て)すると、 1G66tk1RB6 となりましたが、合っているでしょうか。一応10文字にはなりましたが。 あと、HashSumがバイト単位の設定なので7バイトにしましたがこれだと9文字になるパターンも有り得ますよね。 その場合は10文字になるまで、入力値のOKWavePassword_change#_0の最後の0を1とか2とかに変えていけばいいかと思ってますが。 まぁそれ用に項目を置いてOKWavePassword_dummy#0_change#_0とかにしてこの場合dummy#の直後の数字を変えるという決めにするとかしとけば、パスワードを今まで何回変更したか知りたい(そんな要望あるのかはともかく)ときにゴッチャにならないで済むけど。 みたいな細かい問題は出てくると思いますが、このように柔軟に対応できると思っていますが、何か他に対応の難しい問題はありそうですか? 【質問4.全体的にどうでしょうか?】 みたいな。 なんか結局、今まで考えていた通りにSHA-3 512でやっとけば良さそうな気がしてきましたが、全体通して総評ください。 以上、よろしくご回答の程、お願いいたします。

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

> 【質問4.全体的にどうでしょうか?】 手間の割りには、大して効果的ではない。 趣味のプログラムの勉強ならまったく構わないが、セキュリティ的には意味は無い。 ○ seedとアルゴリズムが分からなければ、パスワードを求めるのが困難、という意味では、どのアルゴリズムを使っても大差無い。 それこそ、「無変換」であっても、seedが不明なら、パスワードはわからない。 「これを暗号化する」という思い込みから、かえって「無変換」以外から探そうとするかもしれない。 ○ 攻撃者が欲しいのは、パスワードであって、その作り方ではない 求め方が一致しなくても、パスワードさえ一致すればよい。 結局、総当り攻撃に対しては、どんなやりかたをしても同じ。 ○ハッシュは複雑になることを保証するものではない 求めた結果が「12345678」になることだってある ○ハッシュは1対1対応であることを保証するものではない。 a=b ⇒ H(a)=H(b) である、というだけで 逆を保証するものではない。 myseedがバレなくても H(myseedOKWavePassword_change#_0)=H(yourseedOKWavePassword_change#_0) になっているかもしれない ○ length-extension攻撃を誤解している。 seed: ハンニンハ H(seed|ヤス)=10 H(seed|ヤスジロウ)=13 だとする。 「ヤス、10」と送られてきたら、これはseedを知っている(=信頼できる)人からなので、メッセージを信用する。 「ヤス、10」を知った攻撃者が偽情報「ヤスジロウ」を送って信用させようとすると、ハッシュである13を求めて「ヤスジロウ、13」を送らなけばならない。 ハッシュ関数に期待されるのは、seedが分からなければ、H(seed|ヤスジロウ)も計算できない、というもの。 length-extension脆弱性というのは、これがseedそのものを必要とせず、 H(seed|ヤス)の値10 と、追加する 「ジロウ」というメッセージから、H(seed|ヤスジロウ)=13 が求められてしまう、というもの。 この脆弱性があったところで ・ハッシュ関数のアルゴリズムが不明なら、計算困難 ・H(seed|ヤス)=10 と言った拡張前の情報がなければ計算困難 ・「イエヤス」「コウジロウ」等、既知のメッセージの末尾に追加するのでは無いものについては、計算困難 ・seedが漏洩するわけではない ということです。 ハッシュ付きの実行ファイルの後にウイルスを追加して、それを「信用できる実行ファイル」に偽装する、ということはできるかもしれせん。 しかし、あなたがやろうとしている事について言えば ・seedが漏洩するわけではない ・パスワードに使うのは「10」で、これを公開するわけではない ・「13」が計算できたところで、パスワードとは一致しない。 と、この脆弱性は影響しません。

mojijyouken
質問者

補足

「セキュリティ的には意味は無い。」とぶった切られてしまいましたが、 後半のlength-extension攻撃に関する指摘が長いですが、 同攻撃についてはご説明の通りで、私は誤解してません。 誤解だとしてもそれならSHA-2等、(現時点では)SHA-3より身近なハッシュ関数が利用できるということで、却ってやり易いことになってしまいます。 ひとつひとつ説明しようかと思いましたが、殆ど全部になってしまうので、これは私の質問の仕方が悪いかなと思えてきましたので、また別途、論点を細かく分けて質問しようと思います。。

  • ok-kaneto
  • ベストアンサー率39% (1798/4531)
回答No.2

>どんな文字列に変更すれば良いか考えることが面倒だからこういう事を考えました。 パスワードジェネレーターを使えば良いと思います。 まあ、その安全性が確保できたわけではないですけど。 http://freesoft-100.com/security/password_make.html

mojijyouken
質問者

お礼

回答ありがとうございました。

mojijyouken
質問者

補足

それだと公開でメモしておけないので。 ハッシュの方法だとseedだけ暗記して秘匿すればあとの情報は全公開でも構いませんし。

  • ok-kaneto
  • ベストアンサー率39% (1798/4531)
回答No.1

そこまで面倒な事しなくても、8文字以上で大文字小文字特殊文字組み合わせて定期的に変更したほうが良いのでは、と思いました。

mojijyouken
質問者

お礼

回答ありがとうございました。

mojijyouken
質問者

補足

どんな文字列に変更すれば良いか考えることが面倒だからこういう事を考えました。

関連するQ&A

  • パスワードの決め方について(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 攻撃以外の危険性はありますか?

  • 2のn乗+1

    nビットのハッシュ関数の出力は0から2のn乗の、合計すると2のn乗+1のパターンがあるってことで合ってますか? それとも0から2のn乗-1で、合計2のn乗パターンですか? もしくは0はなくて1から2のn乗までですか? 実際の出力をみると0000……FA16みたいなケースもあるので、そうすると全部0という出力も有り得るのですか? また最大値はn+1ビットも有り得るのですか?最大桁が1で残りが全て0とすると、2のn乗は2進数だと最大桁に1が来て、残りが全部0ですがその0の数は、n個になると思いますが、そうすると何々ビットのハッシュ関数といいつつ、最大値でみるとビット数は2のn乗+1となりますが、認識正しいでしょうか?

  • パスワードのハッシュ化について

    ユーザー登録させるようなwebサイトを作ることになりました。 ググッたところパスワードはハッシュ化させDBへ、っていうのが通常らしいんで、 sha256を使って変換しようと思います。 質問(1)ハッシュ化させる元の文字列には文字数など何か制限はないんでしょうか。 質問(2)ハッシュ化させるときにくっつけるsaltは何桁くらいにするのが一般的なんでしょうか。 教えてください。

  • 暗号学的ハッシュ関数でbit長が適切って作れますか

    SHA256が(224かもですが)最小bit長で、 入力に1bitでも、また2bit以上入力値全体まで、異なれば、 出力のうちほぼ半数のbitが反転する、かつその 反転するbit位置は複数の入力値に対して法則性はなく、 ほぼランダムである。 という暗号学的ハッシュ関数であるのは、正しいですか? また、データの暗号化に使われるパスワードは4096bitを推奨との 事ですが、 SHA4096などその時に合った暗号学的ハッシュ関数を 作るのは難しいのですか? 素人考えでは、今256bitで衝突が見つかってないなら 4096bitならbit長大きいのだから作れそうな気もしますが やはりそういう問題ではないのでしょうか? もし作れるとしたら、データの暗号化に使うパスワードを SHAなんとか・・・の出力そのまま使っては、危険でしょうか? というかデータに限らず認証のパスワードでも SHAなんとかの出力そのままを使うのは何かまずいのでしょうか? もしできたらパスワードを覚えなくてよいのでいいかと思ったのですが。 パスワードは「IDのパスワード」をSHAなんとかに通した値ということで。 IDは「種パスワード+なんとかのサイト」をSHAなんとかに通した値ということで。 種パスワードはしょうがないからネットをパスワードの決め方とかで検索して 出てきた方法を見て理解して自分なりにアレンジして、最後にちゃんと頭に記憶して。 とりあえずここまで、どうでしょうか。

  • なぜパスワードが分かる・・・。?

     ココや、ヤフーなどのフリーメールのサービスなどで、IDとパスワードが必要な場合ってあるかと思います。 もしパスワードを忘れたら、メールで折り返し連絡がくるかと思います。 そこで気になるのですが、普通パスワードって、パスワードをハッシュ関数か何かで暗号化したものを保存しておき、ユーザーが入力したパスワードをハッシュ関数か何かで暗号化して一致するか同かを調べるとどこかで聞いた気がします。 そうだとすればなぜパスワードが分かるのでしょうか?

  • パスワード暗号化

    パスワードを暗号化するにはphp関数などでハッシュ化させてからINSERTするしかないのでしょうか? MYSQL自体に現在INSERTされている文字列をハッシュ化させる方法はないでしょうか?

    • ベストアンサー
    • MySQL
  • なぜハッシュ関数の値をそのままパスワードに使わない

    ハッシュ関数の出力値をそのままパスワードに使うのはなぜ誰もやらないのでしょうか? 変更とか楽でよさそうですが。

  • Opera_9.26_International_Setup.exeのハッシュ値とバイト数

    Opera_9.26_International_Setup.exeのハッシュ値とバイト数 おしえてください。ハッシュ値はMD5かSHA-1 をお願いします。

  • レインボーテーブルとはなんですか?

    レイボーテーブルというのはどのようなものなのですか? ハッシュ値から、パスワードを入手するために、簡単な文字列を入れていき、同じハッシュ値になるか確かめるのですか? それともアルファベット順に調べていくのですか? また、同じSHA256でも、ハッシュ化する方法を変えていれば、既存のレインボーテーブルは使えなくなりますか?

  • パスワードの変更

    会員サイトを作っているのですが会員登録後のパスワード変更について質問です。 パスワードを忘れた際の再発行は秘密の質問等の特定のフィールドの値と入力された 値が一致すれば再発行で問題ないと思いますがマイページからパスワードを変更する 際に登録時に設定した文字数で表示されますよね?厳密には『●』で表示されますが。 一般的には、ハッシュ化した値を登録するかと思うのでどうやって実現しているのかわかりません。 方法が思いつかないのですが単純にハッシュ化する前のパスワードの文字数を専用の フィールドに登録しその文字数と同数『●』で表示しているだけですか? 調べてもわからなかったので教えてください。

    • ベストアンサー
    • PHP