| « Windows税の返金? | PostgreSQLでSHA1 » |
SHA1でハッシュ化したパスワードは危険になった
リンク: http://it.slashdot.org/it/07/01/20/1936257.shtml?tid=172
パスワードを平文で保存するのは論外で、MD5やSHA1でハッシュ化するのは当たり前です。しかし、SHA1を2000倍早くクラックする方法などが発見され「SHA1は脆弱だ」(ちなみにMD5はもっと危険)とされてからしばらく経ちます。アメリカ政府や大手企業はSHA1は使わない、としています。
# Slashdot.orgにまた載っているので更に高速化できた、と言うことかな?
前のエントリ
http://blog.ohgaki.net/index.php/yohgaki/2007/01/23/postgresqla_ssha1
でPostgreSQLでSHA1を使う方法の一つを紹介していますが可能であればSHA512など、より強いハッシュ関数を利用したり、Saltを利用する、等の方法を採用した方が良いと思います。
備考:良いハッシュ関数の性質として不可逆性があります。例えば、パスワードを「abcd789oiuy」に設定した場合、SHA1ハッシュは「8bd7c6d4024410b312a89a9e13a9b0e8826cce31」になります。良いハッシュ関数はハッシュ値からパスワードが「abcd789ouiy」である事を推測できない性質を持っていなければなりません。そうでないとハッシュ値からパスワードを解析できる事になります。
Saltを利用した場合、仮にパスワードデータが漏洩しても、Saltも知っていないと認証を行えるパスワードを推測・解析できないのでより安全になります。つまり、
$hashed_password = sha512($_POST['password'].'固定の秘密文字列');
等としてハッシュ化したパスワードデータの方がより安全です。当然ですがパスワードデータだけでは辞書攻撃もできなくなります。
15 コメント
ご指摘ありがというございます。
http://b.hatena.ne.jp/HiromitsuTakagi/
にも少しかかれていますが。
Saltは、通常はハッシュ値の先頭に平文で付けるものですよね。
(/etc/shadowなどで使われている)。
Saltの目的は、
・同じパスワードが同じハッシュ値になることを避ける
・レインボー攻撃を難しくする
などで、秘密情報という意味合いは薄いように思います。
ところで、パスワードの保存には、Saltと秘密情報の両方を使う方がよいと思います。
ただ、秘密情報をどう安全に保存するか? というのは難しいですね。
> Saltは、通常はハッシュ値の先頭に平文で付けるものですよね。
古いUNIXでどのように使われていたかは知っています(UNIXの場合、Saltは公開情報なので「ぱっと見ただけで自分と同じパスワードを使っている人が判らない程度」の安全性を提供しているだけです。学生の頃は遊びでクラックプログラムも作ったりもしました。この時Joeパスワードを使っている人が多いのにも驚かされました)が、ここで例示したかったのは「SHA1でハッシュ化」しただけだと辞書攻撃で簡単にクラックされてしまう、難しいパスワードであっても同じハッシュ値となる文字列を比較的簡単に割り出せてしまう、と言うことです。UNIXのパスワードシステムと違って、WebアプリにSaltを使った場合、一般ユーザには公開しなくても問題ありません。(と言うより秘密にしておくべき)このエントリのSlatの目的は「万が一ハッシュ化されたパスワードが漏洩」しても解析できないようにする事です。ですからSaltの位置は場所は決めなければならないですが、最初でも最後でも、途中でも構いません、Saltを使ったマスク処理をしても構いません。
# ところで、少なくとも「辞書攻撃」(dictionary attack)という用語は17,18
# 年前から利用されています。恐らくもっと昔から利用されていたと思います。
# より分かり易い名前ならともかく「レインボー攻撃」と分かりづらい名前で
# 呼ぶのは適切なのか疑問に思います。
多くのセキュリティの指針等でも「平文のパスワードは保存すべきではない」としています。クローズドなシステムでパスワードの安全性が100%保障できるのであれば平文のパスワードを保存しても構わない、といった話になるのですがパスワードは非常に重要な情報なので平文で保存すべきではない、とされています。同じSHA1ハッシュを生成する文字列を簡単に割り出せるのであれば、単純にSHA1でハッシュ化したパスワードは平文と変わらないことになります。
要はパスワードは元々機密情報ですが特に重要なので、参照できないようにする・参照しただけでは判らないようにする・解析できないようする・解析を難しくする、事が必要でその一つとしてSaltがある、と言うことです。
今のところSHA512などは安全と考えても良いですが、将来その安全性が脅かされる可能性もあります。ハッシュ化したパスワードが分かり、Saltも分かっている場合、あまりに単純なパスワードを使用しているユーザの安全性はどのようなハッシュ関数を使っていても守れません。Slatを使っていてもコリージョンを起こす文字列を発見する攻撃を100%防ぐ事ができる訳ではありません。だた攻撃しようとしているクラッカーに対する障壁を高くすることにはなります。
> ただ、秘密情報をどう安全に保存するか? というのは難しいですね。
余分な情報をつけるのは万が一、データベースの情報が漏洩した場合のリスクを少なくする為の方法なので「ハードコードされた秘密の文字列」を秘密にしておくは非常に難しい、と言うより基本的には無理、ソースにアクセスできる人には公開情報なので「ちょっと見た程度では覚えられないくらい長い文字列にする」というくらいの対策しか取れないです。
salt付きでハッシュ化するのが無意味か?と言われるとSHA1でハッシュ化されたパスワードをクラックするツールが数多くある現状を考えると、多少は意味がある、と言えると思います。複数のsaltを使うようにすると更に解析が難しくなります。どこまでやるか?はニーズに応じて、と言うことになると思います。
しかし、このエントリで「論外」としている平文パスワードを保存しているサイトも多いと思います。今日、Adobeストアのパスワードを忘れたのでリクエストするとパスワードがそのままメールで送られてきました... Adobe的にはコレでいいのかな... 他の大手サイトでもパスワード送ってくるサイトありますね... 「大手がそうしているから」と言ってもその方法がお勧めできる方法でない場合も多いです。
とにかく、ないには越した事はないですが万が一SQLインジェクション等でユーザ名とハッシュ化したパスワードの一覧を盗まれても簡単にパスワードを解析できないようにするのは意味があると思います。Webユーザの多くが非常に簡単なパスワードかつ複数サイトで同じパスワードを使いまわしていますから...
ご指摘の通り、レインボー攻撃は一般的じゃない言葉かもしれませんね。ただ、辞書攻撃には、辞書単語を使うだけで、事前にそのハッシュを用意しないタイプの攻撃も含まれると思います。それと区別するためにレインボー攻撃と呼びました(事前にハッシュを用意しておくタイプの攻撃を指す言葉が判りませんでした)。
それから、Salt(ユーザ毎に異なる情報)と、秘密情報(共通の情報)では、その目的が違いますよね。後者のこともSaltって呼ぶんでしょうか?
あとパスワードクラッカーツールは SHA-1 ハッシュ値を解析しているわけではなく辞書攻撃などさまざまなクラック手法を駆使しています。salt は確かに辞書攻撃には一定の抵抗力がありますが万能ではありません。故にパスワード文字列をどう設定するかが決定的に重要になるわけです。
パスワードに追加の値を含めてる事を総称してSlatと呼ぶのが一般的か?と聞かれると疑問ですね。
UNIXパスワードのSaltは「味付け」の意味で使っていると思います。別の言葉を使うとするとマジック
くらいでしょうか?どちらにしてもこの使い方で一般的に広く使われている用語は知りません。
その通りですね。
時々パスワードの長さを制限しているシステムを見かけますが、よくないと
思っています。
最近の研究では「センテンスを使ったパスワードは十分に長いランダム文字列
と同程度に強固だ」としていたりします。例えば、
「娘の大好きな番組は二人はプリキュアとお願いマイメロディです」
等とする(実際には英数字で書かなければならないシステムがほとんどだと
思います)と十分に強力かつユーザにとっても覚えやすいです。32文字まで
などと制限するとこのようなパスワードは設定できないです。
そうですね。私も昔辞書攻撃するツールは遊びで作った事があります。(学生はいろいろ試してみる物ですよね?違う?)
私が言いたかったのは「SHA1で特定のハッシュ値となる同じ文字列を十分な速さ計算できる」のであれば「SHA1でハッシュ化した"難しい"パスワードも解析される危険性がある」と言うことです。元々パスワード情報は機密情報なので守られていて当然な情報ですが、事故やシステム管理者からの攻撃から守る為、パスワード情報は安全に管理するだけでなく誰も知りえない状態になっているべきと考えています。SHA1ハッシュ関数がその用途にも使われてきましたが役目は終えて、更に強固なSHA2(SHA256、SHA512など)ハッシュ関数を使用する時期ではないかと思っています。
「SHA-1 から SHA-2 に切り替えよう」という話には同意できますがパスワード認証を例に挙げるのはちょっと違うと思います。
あと、ご存知と思いますが、NIST は SHA に代わる新しいハッシュアルゴリズムを探していて、場合によっては SHA そのものが10年以内にお払い箱になる可能性があります。要は(少なくとも新規のシステムにおいては)特定のアルゴリズムに依存しない設計が要求されているということですね。
ハッシュ関数は改ざんチェックに利用される事が多く、一番攻撃対象となり易い
のが文書の改ざんと思っています。
このエントリ自体は前のハッシュ化したパスワードの取り扱いを書いたときにSHA-1
を使って説明していたので、実はSHA-1でハッシュ化しただけのパスワードだと解
析されるリスクが高くなっている、と説明することが意図だったので分かり辛かった
ですね。
でもこういった感じでコメントを付けて頂けると判りづらい部分も直せるので
助かります :)
> 場合によっては SHA そのものが10年以内にお払い箱になる可能性があります
MD5から派生した系のハッシュ(その他もですが)は設計自体に問題がある
のではないかと言われていますね...
開発者としては「どれでも良いから誰か信頼できるハッシュ関数作って」という
のが本音です。
http://en.wikipedia.org/wiki/Salting_%28cryptography%29
In cryptography, a salt consists of random bits used as one of the inputs to a key derivation function.
The salt value may, or may not, be protected as a secret. In either case, the additional salt data makes it more difficult to conduct a dictionary attack against for example, a password file, using pre-encryption of dictionary entries.
In some protocols, the salt is transmitted as cleartext with the encrypted data, sometimes along with the number of iterations used in generating the key (for key strengthening).
>より分かり易い名前ならともかく「レインボー攻撃」と分かりづらい名前で呼ぶのは適切なのか疑問に思います。
相手を非難する前に自分の無学を疑わないといつまで経っても自分の間違った知識に気づけませんよ。以下を読んでください。
http://en.wikipedia.org/wiki/Rainbow_tables
>
>http://en.wikipedia.org/wiki/Salting_%28cryptography%29
>In cryptography, a salt consists of random bits used as one of the inputs to a key derivation function.
>
>The salt value may, or may not, be protected as a secret. In either case, the additional salt data makes it more >difficult to conduct a dictionary attack against for example, a password file, using pre-encryption of dictionary >entries.
>
>In some protocols, the salt is transmitted as cleartext with the encrypted data, sometimes along with the >number >of iterations used in generating the key (for key strengthening).
まさしくこう説明されている事を頭の中では意図しているのですがSaltの説明をしているつもりではなかったのでわかりづらかったようですね。
>>より分かり易い名前ならともかく「レインボー攻撃」と分かりづらい名前で呼ぶのは適切なのか疑問に思います。
>
>相手を非難する前に自分の無学を疑わないといつまで経っても自分の間違った知識に気づけませんよ。以下を読んでください。
>
>http://en.wikipedia.org/wiki/Rainbow_tables
こういうテーブルをレインボーテーブルと割と一般的(?)に呼ばれている事は知っています。(知らないと思います??)
そういう事でなく、単純な言い換えや直感的にわかり辛い名前もあるので、わざわざわかり辛い方を利用するのはよくない、と思っていると言う事です。レインボーテーブルの場合、少なくとも辞書攻撃の方がずっと前から一般的に利用され、「辞書攻撃」といった方が「レインボーテーブル攻撃(またはレインボーテーブルを使った攻撃)」より直感的に解りやすいと思います。
# 解りやすさとなると個人の感覚の問題もあるので絶対的なものではないです。
# 「レインボーテーブル」という呼び方もずいぶん前からですし。
こういった基本的なことを知らないと勘違いされる時点で書き方の問題があるといえると思いますが、フォーマルに解りやすい解説文を意図している訳ではないので、適宜行間を読んでください。
今回は誤解(書き方の問題)と思いますが、間違っているのでは?と思われる点へのツッコミはいつでも大歓迎です。
人は間違えるものですし、完璧ではありません。
完璧ならとっくにソフトウェアは安全になってます(苦笑