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

パスワードを最大限に複雑に決めたいとします。

当然、覚えられないので、適当な言葉で決めて、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でやっとけば良さそうな気がしてきましたが、全体通して総評ください。

以上、よろしくご回答の程、お願いいたします。

A 回答 (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」が計算できたところで、パスワードとは一致しない。
と、この脆弱性は影響しません。

この回答への補足

「セキュリティ的には意味は無い。」とぶった切られてしまいましたが、

後半のlength-extension攻撃に関する指摘が長いですが、
同攻撃についてはご説明の通りで、私は誤解してません。

誤解だとしてもそれならSHA-2等、(現時点では)SHA-3より身近なハッシュ関数が利用できるということで、却ってやり易いことになってしまいます。

ひとつひとつ説明しようかと思いましたが、殆ど全部になってしまうので、これは私の質問の仕方が悪いかなと思えてきましたので、また別途、論点を細かく分けて質問しようと思います。。

補足日時:2014/07/22 02:25
    • good
    • 0

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


パスワードジェネレーターを使えば良いと思います。
まあ、その安全性が確保できたわけではないですけど。

http://freesoft-100.com/security/password_make.h …

この回答への補足

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

補足日時:2014/07/05 14:48
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/07/05 14:49

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

この回答への補足

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

補足日時:2014/07/05 10:01
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/07/05 10:02

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