More Related Content
Lambda layerをDeployする方法を調べる メルカリ・ソウゾウでは どうGoを活用しているのか? 【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方 XXE、SSRF、安全でないデシリアライゼーション入門 What's hot (20)
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) CyberChefの使い方(HamaCTF2019 WriteUp編) OAuth 2.0のResource Serverの作り方 BuildKitによる高速でセキュアなイメージビルド AWS Organizations連携サービスの罠(Security JAWS 第26回 発表資料) UnicodeによるXSSとSQLインジェクションの可能性 乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料) Azure Cosmos DB のキホンと使いドコロ MHA for MySQLとDeNAのオープンソースの話 Similar to Webアプリでパスワード保護はどこまでやればいいか (20)
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2011 今日こそわかる、安全なWebアプリの作り方2010 『例えば、PHPを避ける』以降PHPはどれだけ安全になったか 徳丸本に載っていないWebアプリケーションセキュリティ Strata + Hadoop World 2014 レポート #cwt2014 著名PHPアプリの脆弱性に学ぶセキュアコーディングの原則 「新しい」を生み出すためのWebアプリ開発とその周辺 脆弱性は誰のせい? PHP、MySQL、Joomla! の責任やいかに リスクを低減するためのクラウド型OSS管理ツールOpenLogic および Zend PHP IVS CTO Night & Day 2016 Tech Talk - AI More from Hiroshi Tokumaru (20)
SPAセキュリティ入門~PHP Conference Japan 2021 脅威分析の手法によりウェブサーバーにウイルス対策ソフトが必要かを検証する introduction to unsafe deserialization part1 SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方 ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題 オニギリペイのセキュリティ事故に学ぶ安全なサービスの構築法 (PHPカンファレンス2019) Railsエンジニアのためのウェブセキュリティ入門 デバッガでWordPress本体やプラグインの脆弱性を追いかけてみよう CMS四天王への攻撃デモを通じて、WordPressの効果的な防御法を学ぼう Webサイトをめぐるセキュリティ状況と効果的な防御方法(WordPress編) Webアプリでパスワード保護はどこまでやればいいか
- 1. YAPC::ASIA TOKYO 2011
Webアプリでパスワード保護は
どこまでやればいいか
HASHコンサルティング株式会社
徳丸 浩
twitter id: @ockeghem
Copyright © 2011 HASH Consulting Corp. 1
- 2. 徳丸浩の自己紹介
• 経歴
– 1985年 京セラ株式会社入社
– 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍
– 2008年 KCCS退職、HASHコンサルティング株式会社設立
• 経験したこと
– 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当
– その後、企業向けパッケージソフトの企画・開発・事業化を担当
– 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当
Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始
– 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち上げ
• 現在
– HASHコンサルティング株式会社 代表 http://www.hash-c.co.jp/
– 京セラコミュニケーションシステム株式会社 技術顧問 http://www.kccs.co.jp/security/
– 独立行政法人情報処理推進機構 非常勤研究員 http://www.ipa.go.jp/security/
• その他
– 本を書きました「体系的に学ぶ 安全なWebアプリケーションの作り方」
– 電子版キャンペーン中(10月17日まで): http://bookpub.jp/books/bp/144
Copyright © 2011 HASH Consulting Corp. 2
- 10. まだまだ続く…
Copyright © 2011 HASH Consulting Corp. 10
- 11. しかし、訂正が入る
Copyright © 2011 HASH Consulting Corp. 11
- 19. ということで、本日お話ししたいこと
• そもそも、パスワードだけ保護する理由は?
– パスワードが漏れているということは他の個人情報も漏れているよね
• どうして暗号化ではなくてハッシュなの?
• ハッシュで保存されたパスワードは本当に安全なの?
• ハッシュから平文パスワードに戻す方法はないの?
• MD5なら危険で、SHA-256なら安全なんでしょ?
• Rainbow Tableってなに?
• Saltってなに?
• Stretchingってなに?
• 結局どうすればよいの?
Copyright © 2011 HASH Consulting Corp. 19
- 22. オンラインクラックとオフラインクラックをごっちゃにした記事の例
これはオフラインクラック
を想定している
これはオンラインクラックの文脈
だが、1秒間に1000万回は無理
http://www.itmedia.co.jp/enterprise/articles/1012/07/news010_2.html より引用 22
- 23. そもそも、パスワードだけ保護する理由は?
• パスワードが漏れている状況では、他の個人情報も漏れている
可能性が高い
• しかし、情報漏洩だけが「困ること」ではない
– 利用者の権限で使える機能の悪用
– 利用者のアカウントでの投稿など
• オバマ大統領に成りすましてtwitterでつぶやく、とか
• パスワードを他のサイトでも使い回ししている利用者がいる
– サイト運営者は、パスワードを使い回ししている利用者のせいにしてはい
けない
• パスワードを可能な限り保護することは、サイト運用者の責務
Copyright © 2011 HASH Consulting Corp. 23
- 24. オンラインクラックのパターン
• 総当たり攻撃(Brute force attack)
• 辞書攻撃(Dictionary attack)
• その他のバリエーション
– ジョーアカウント(Joe account)探索
– 逆総当たり攻撃(Reverse brute force attack)
総当たり攻撃 辞書攻撃 ジョーアカウント探索 逆総当たり攻撃
user01:aaaaaa user01:password user01:user01 user01:password
user01:aaaaab user01:123456 user02:user02 user02:passowrd
user01:aaaaac user01:qwerty user03:user03 user03:passowrd
user01:aaaaad user01:root user04:user04 user04:passowrd
user01:aaaaae user01:99999 user05:user05 user05:passowrd
・・・ ・・・ ・・・ ・・・
Copyright © 2011 HASH Consulting Corp. 24
- 25. オンラインクラック対策
• 当然ながらパスワード情報が漏れないよう守ることが先決
• 利用者に「強い」パスワードをつけてもらう
– 長いパスワードが有効(最低でも8文字)
– Amazonは、すべてのASCII文字128文字までが使える
• アカウントロックが基本
– ログインID毎にパスワード間違いを記録し、連続してN回間違えた場合、
X分アカウントを無効にする
– N=6~10 X=30~60
• しかし、ジョーアカウント探索や逆総当たり攻撃には、単純なアカ
ウントロックでは対処できない
• ジョーアカウント攻撃や逆総当たり攻撃への対策例
– 「悪い」パスワードをチェックしてはじく(例:twitter) DEMO
– ログインIDを秘匿する(メールアドレスを用いる場合が多い)
• 例:facebook、mixi、Amazon
徳丸は自衛のためログイン用の
– ログイン失敗率の監視 メールアドレスを使い分けている
Copyright © 2011 HASH Consulting Corp. 25
- 26. 【参考】Yahoo!の場合
これくらい多いと、攻撃
も「埋もれてしまう」かも
http://bakera.jp/ebi/topic/4140 より引用 26
- 27. 続いて、オフラインの話
Copyright © 2011 HASH Consulting Corp. 27
- 28. どうして暗号化ではなくてハッシュなの?
• 暗号化の場合、鍵の管理が難しい
• アプリケーションは鍵を使わなければならないが、攻撃者には鍵
を見せたくない
• PSNの事件では、権限昇格されたことになっているので、暗号鍵
も盗まれていると想定せざるを得ない
• ハッシュだと鍵を使わないので、鍵管理のわずらわしさがない
• パスワードをサイト管理者にも知られたくないというニーズも
– 暗号化されたパスワードだと、サイト管理者やヘルプデスク担当者がパス
ワードを知り得るのが嫌だ
– ヘルプデスクに見せないようにするには、サポート用画面の機能次第で可
– 管理者の悪事は総合的な対策が必要で、パスワードの問題だけではない
• PCI-DSS2.0 8.4項には「8.4 強力な暗号化を使用して、すべて
のシステムコンポーネントでの伝送および保存中のすべてのパ
スワードを読み取り不能にする」とあり、ハッシュを求めてはいな
い
Copyright © 2011 HASH Consulting Corp. 28
- 29. ハッシュで保存されたパスワードは本当に安全なの?
• 一般的に、(暗号論的)ハッシュ値から平文を「復元する」ことはで
きない
– 「password」のMD5ハッシュ: 5f4dcc3b5aa765d61d8327deb882cf99
• しかし、パスワードの場合は特別な事情がある
• 例:4桁の暗証番号をハッシュ値で保存している場合
– 全ての可能性は1万通りしかないのだから、総当たりで確認すれば、平文
の暗証番号はすぐに判明する
• 原理は8桁パスワードでも同じ
• ハッシュ保存の場合、アルゴリズムは攻撃者が知っている前提で
安全な設計とする
– 平文パスワード以外は、すべて「ばれている」想定を置く
• 攻撃者にとって未知であることが保証された情報があれば、それ
を鍵として暗号化すればよい。現実にはそのような保証がないか
ら暗号化を用いない
Copyright © 2011 HASH Consulting Corp. 29
- 30. ハッシュから平文パスワードに戻す方法はないの?
• 「徳丸本」で紹介している方法
• 総当たり攻撃
• 辞書攻撃
• レインボークラック
• ユーザDBにパスワード辞書を作る
Copyright © 2011 HASH Consulting Corp. 30
- 31. 総当たり攻撃・辞書攻撃
• オフライン型のパスワードクラックツールが該当
– John the Ripperなど
• さまざまなパスワードの「候補」からハッシュ値を求めて照合する
総当たり攻撃のイメージ 辞書攻撃のイメージ
aaaaaa password
aaaaab 123456
aaaaac qwerty
aaaaad pokemon
aaaaae root
... ...
• 「辞書」の内容としては、よく使われるパスワードの他、ユーザID
そのもの(Joeアカウント)、組織名なども含める
Copyright © 2011 HASH Consulting Corp. 31
- 32. 総当たり攻撃って遅いんでしょ
• そうでもない
• ハッシュ関数は高速性が求められる
– 電子署名などの用途では、高速であるほどよい
– DVD-ROMイメージ全体のハッシュ値を求めたりする
• パスワード保護の目的では、高速性は要らない
– むしろ、平文解読も「高速」になってしまう
• こういう記事も
http://slashdot.jp/security/article.pl?sid=11/06/06/0023219 より引用
Copyright © 2011 HASH Consulting Corp. 32
- 34. Rainbow Tableってなに?
• Rainbow Tableとは、ハッシュ値から平文を求めるための逆引き
表の一種
• 単純な逆引き表だと、データ量が膨大になる
• 7文字英数字(小文字のみ)のパスワードで計算してみる
– 可能なパスワードの総数は (26+10) ^ 7 = 78,364,164,096
– パスワード 7バイト + ハッシュ128ビット(16パイト) = 23バイト
– 23 × 78,364,164,096 = 1,802,375,774,208 約 1.6テラバイト
• 8文字 ASCII文字 だと
– 95 ^ 8 × (16 + 8) = 159,220,903,509,375,000 (159ペタバイト ! )
• 大幅にデータ圧縮しないと実現できないが、そんなことが可能か
→ 還元関数というアイデアにより実現
Copyright © 2011 HASH Consulting Corp. 34
- 35. レインボーテーブルとは
逆引き表 レインボーテーブルの格納イメージ
• 逆引き表はサイズが膨大になり現
実的でない
• 表のサイズを小さくするアイデアは
ないか
• 還元関数というアイデア
還元関数のレインボーテーブルのチェーン
還元関数はハッシュ値から
パスワードを生成する
Copyright © 2011 HASH Consulting Corp. 35
- 37. 大きなハッシュテーブルは売っている
http://project-rainbowcrack.com/buy.php 37
- 39. ユーザDBにパスワード辞書を作る
未知のハッシュ関数でもこの方法で攻撃可能
Copyright © 2011 HASH Consulting Corp. 39
- 40. MD5なら危険で、SHA-256なら安全なんでしょ?
• ハッシュ値から平文パスのワードを求める手法は、いずれもMD5
固有の特性(脆弱性)を使っていない
• いずれも、総当たり攻撃、辞書攻撃やこれらの変形である
• したがって、既知のハッシュ関数であれば、前述の攻撃手法が適
用可能
• SHA-1用のレインボーテーブルは既に公開されている。SHA-
256用なども、ニーズがいずれは公開されるハズ
• たまに、「MD5によるパスワード保存は危険」とか「SHA-1による
パスワード保存もそろそろ危険」とか書いている文書があるが、
たいてい間違い
Copyright © 2011 HASH Consulting Corp. 40
- 41. Saltってなに?
• ソルト(Salt)とは、ハッシュの元データ(パスワード)に追加する文
字列
• 見かけのパスワードの長さを長くする
– 公開されたレインボーテーブルは10文字までのパスワードに対応している
ので、パスワードとソルトを合わせて20文字以上にしておけば、当面は大
丈夫
• ユーザ毎にソルトを変えることで、パスワードが同じでも、異なる
ハッシュ値が得られる
• ソルトの要件
– ある程度の長さを確保すること
– ユーザ毎に異なるものにすること
• ソルトには乱数を用いることが多いが、乱数が必須というわけで
はない(暗号論的に安全な乱数である必要はもちろんない)
• ソルトは秘密情報ではない。ソルトは、通常ハッシュ値と一緒に
保存する
Copyright © 2011 HASH Consulting Corp. 41
- 42. Stretchingってなに?
• ストレッチング(Stretching)とは、ハッシュの計算を繰り返すこと
• ハッシュの計算を遅くすることにより、辞書攻撃や総当たり攻撃
に対抗する
• 1万回ストレッチすると、「 GPU で 7 時間である」が7万時間にな
る計算
– 7万時間 = 2916日 = 約8年
• 「悪い」パスワードまで救えるわけではない
– 「password」というパスワードをつけていたら、100万回ストレッチしてもす
ぐに解読されてしまう
• 十分長いパスワードをつけてもらえば、ストレッチングは必要ない
– 1文字パスワードを長くすることは、約100回のストレッチングに相当する。
パスワードを2文字長くしてもらえば…
– でも、中々難しいのでストレッチングの値打ちがある
• ストレッチングはメリットとデメリットがあるので、導入の有無と回
数をよく検討すること
Copyright © 2011 HASH Consulting Corp. 42
- 44. ソルトとストレッチングのスクリプト例(Perl)
#!/usr/bin/perl
use strict;
use warnings;
use Digest::SHA qw(sha256_hex);
# FIXEDSALTはサイト毎に変更してください
my $FIXEDSALT = 'bc578d1503b4602a590d8f8ce4a8e634a55bec0d';
my $STRETCHCOUNT = 1000;
# ソルトを生成する
sub get_salt {
my ($id) = @_;
return $id . pack('H*', $FIXEDSALT); # ユーザIDと固定文字列を連結
}
# ソルト化ハッシュを繰り返し求める(ストレッチング)
sub get_password_hash {
my ($id, $pwd) = @_;
my $salt = get_salt($id);
my $hash = ''; # ハッシュの初期値
for (my $i = 0; $i < $STRETCHCOUNT; $i++) {
$hash = sha256_hex($hash . $pwd . $salt); # ストレッチング
}
return $hash;
}
Copyright © 2011 HASH Consulting Corp. 44
- 45. パスワードの暗号化は本当に無理?
• 暗号鍵を安全に保管できればOK
• HSM(Hardware Security Module)はどうよ?
Web Application
認証プログラム
HSM API
HSMの呼び出しシー
パスワード パスワード ケンスを解析されると、
暗号化 復号 不正プログラムから
HSM経由でパスワー
ドを解読される
HSM
鍵を安全に保管(耐タンパ性)
• 一見良さそうだが…
• アプリケーションサーバーに侵入された状況では、HSMの呼び
出し元が正規プログラムか不正プログラムかの区別が難しい
Copyright © 2011 HASH Consulting Corp. 45
- 46. HSMを使ったパスワード保存の可能性
• パスワードは復号しなくても照合可能
Web Application
認証プログラム
HSM API
パスワードのハッシュ
パスワード パスワード 値での保存と同じで、
暗号化 復号 暗号化パスワード同
士で比較すれば、復
号しなくても照合可能
HSM
鍵を安全に保管(耐タンパ性)
• 暗号鍵はHSMが安全に守るので、オフライン攻撃は不可能に
• 実現性については問い合わせ中(復号を殺せるか等)→OK
• HSMの価格は数十万円~一千万円(!)
Copyright © 2011 HASH Consulting Corp. 46
- 47. パスワードをハッシュで保存する場合の課題
• 「パスワードリマインダ」が実装できない
– 「秘密の質問」に答えるとパスワードを教えてくれるアレ
– 絶滅危惧種…でもないか
– パスワードリセットで代替
• ハッシュの形式(アルゴリズム、ソルト、ストレッチ)の変更
– 生パスワードが分からないのでハッシュの方式変更がバッチ処理ではでき
ない
– ユーザの認証成功の際にはパスワードが分かるので、その際に方式を変
更すると良い
– 緊急を要する場合は、現在パスワードを無効にして、パスワードリセットで
– ハッシュ値あるいは別フィールドに「方式番号」をもっておく
$1$d641fdabf96912$4b3c3e95dfab179ebfef220172f58171
方式番号 ソルト ハッシュ値
Copyright © 2011 HASH Consulting Corp. 47
- 48. 結局どうすればよいの?
• パスワード認証は、利用者とサイト運営者が責任を分かち合って
いる
• 利用者に、よいパスワードをつけてもらうのが本筋
• オンライン攻撃に備えて、以下を実施する
– アカウントロックの実装
– SQLインジェクションなどの脆弱性対処
– sshなどの管理用サーバーは公開鍵認証のみに
• オフライン攻撃対策は中々決め手がない
– ソルトなしのハッシュは、レインボーテーブルで元パスワードが簡単に求め
られる
– ソルトは必須。できるだけストレッチングもする
– DBのパスワード欄に余裕を持たせ、方式を改良できるようにしておく
• SQLインジェクションが主な脅威である場合は、ハッシュに加え
て暗号化するという考え方もある
Copyright © 2011 HASH Consulting Corp. 48
- 49. まとめ
• パスワード認証に対する攻撃はオンラインとオフライン
• パスワードをハッシュで保存するのは、パスワード情報が盗まれ
た後に、パスワードを保護するため
• PSN事件のように、権限昇格されてもできるだけパスワードは守
りたい。そのために暗号化ではなくハッシュを用いる
• 単純なハッシュだと簡単に平文パスワードが分かってしまう
– レインボークラック
– 辞書攻撃
– 総当たり攻撃
• GPUの高速化に伴い、8文字パスワードはそろそろ限界
• ハッシュとともにソルトとストレッチングを使いましょう
• それでも心配な場合は、ハッシュをさらに暗号化する方法も
• 今後はHSMの活用も視野に…
Copyright © 2011 HASH Consulting Corp. 49