|
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <!-- $Revision$ --> |
3 | | -<!-- EN-Revision: b8e1b1357def73f310c9f7405035b3acc0cb1eaf Maintainer: takagi Status: ready --> |
| 3 | +<!-- EN-Revision: f012b2761819e0ab25ff8cf4bac6655cfbc6fcff Maintainer: takagi Status: ready --> |
4 | 4 | <!-- Credits: mumumu --> |
5 | 5 | <chapter xml:id="faq.passwords" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"> |
6 | | - <title>安全なパスワードハッシュ</title> |
| 6 | + <title>安全に、かつセキュアにパスワードをハッシュする</title> |
7 | 7 | <titleabbrev>パスワードのハッシュ</titleabbrev> |
8 | 8 |
|
9 | | - <para> |
| 9 | + <simpara> |
10 | 10 | この節では、なぜハッシュ関数を使ってパスワードを守るのかについての理由と、 |
11 | 11 | ハッシュ処理を効率的に行う方法について説明します。 |
12 | | - </para> |
| 12 | + </simpara> |
13 | 13 |
|
14 | 14 | <qandaset> |
15 | 15 | <qandaentry xml:id="faq.passwords.hashing"> |
16 | 16 | <question> |
17 | | - <para> |
| 17 | + <simpara> |
18 | 18 | なぜ、アプリケーションのユーザーが登録したパスワードをハッシュしなければならないのですか? |
19 | | - </para> |
| 19 | + </simpara> |
20 | 20 | </question> |
21 | 21 | <answer> |
22 | | - <para> |
| 22 | + <simpara> |
23 | 23 | パスワードのハッシュは、最も基本的なセキュリティ要件のひとつです。 |
24 | | - ユーザーからパスワードを受け取るアプリケーションを設計するときには必ず考慮しなければなりません。 |
25 | | - ハッシュしなければ、パスワードを格納したデータベースが攻撃を受けたときにパスワードを盗まれてしまいます。 |
26 | | - それは即時にアプリケーションが乗っ取られることにつながるし、 |
| 24 | + ユーザーからパスワードを受け取るアプリケーションやサービスを設計するときには必ず考慮しなければなりません。 |
| 25 | + ハッシュしなければ、パスワードを格納したデータストアが攻撃を受けたときにパスワードを盗まれてしまいます。 |
| 26 | + それは即時にアプリケーションやサービスが乗っ取られることにつながるし、 |
27 | 27 | もしそのユーザーが他のサービスでも同じアカウント・同じパスワードを使っていればさらに被害が大きくなります。 |
28 | | - </para> |
29 | | - <para> |
| 28 | + </simpara> |
| 29 | + <simpara> |
30 | 30 | ユーザーのパスワードにハッシュアルゴリズムを適用してからデータベースに格納しておくと、 |
31 | 31 | 攻撃者が元のパスワードを知ることが難しくなります。 |
32 | 32 | とはいえ、パスワードのハッシュ結果との比較は可能です。 |
33 | | - </para> |
34 | | - <para> |
35 | | - しかし、ここで注意すべき点は、パスワードのハッシュ処理はあくまでもデータベースへの不正アクセスからの保護にすぎず、 |
36 | | - アプリケーション自体に不正なコードを注入される攻撃からは守れないということです。 |
37 | | - </para> |
| 33 | + </simpara> |
| 34 | + <simpara> |
| 35 | + しかし、ここで注意すべき点は、パスワードのハッシュ処理はあくまでもデータストアへの不正アクセスからの保護にすぎず、 |
| 36 | + アプリケーションやサービス自体に不正なコードを注入される攻撃からは守れないということです。 |
| 37 | + </simpara> |
38 | 38 | </answer> |
39 | 39 | </qandaentry> |
40 | 40 | <qandaentry xml:id="faq.passwords.fasthash"> |
41 | 41 | <question> |
42 | | - <para> |
| 42 | + <simpara> |
43 | 43 | よく使われるハッシュ関数である <function>md5</function> や |
44 | 44 | <function>sha1</function> は、なぜパスワードのハッシュに適していないのですか? |
45 | | - </para> |
| 45 | + </simpara> |
46 | 46 | </question> |
47 | 47 | <answer> |
48 | | - <para> |
| 48 | + <simpara> |
49 | 49 | MD5 や SHA1 そして SHA256 といったハッシュアルゴリズムは、 |
50 | 50 | 高速かつ効率的なハッシュ処理のために設計されたものです。 |
51 | 51 | 最近のテクノロジーやハードウェア性能をもってすれば、 |
52 | | - これらのアルゴリズムの出力をブルートフォースで(力ずくで)調べて元の入力を得るのはたやすいことです。 |
53 | | - </para> |
54 | | - <para> |
55 | | - 最近のコンピュータではハッシュアルゴリズムを高速に「逆算」できるので、 |
| 52 | + これらのアルゴリズムの出力を<quote>ブルートフォース</quote> で(力ずくで)調べて元の入力を得るのはたやすいことです。 |
| 53 | + </simpara> |
| 54 | + <simpara> |
| 55 | + 最近のコンピュータではハッシュアルゴリズムを高速に<quote>逆算</quote> できるので、 |
56 | 56 | セキュリティ技術者の多くはこれらの関数をパスワードのハッシュに使わないよう強く推奨しています。 |
57 | | - </para> |
| 57 | + </simpara> |
58 | 58 | </answer> |
59 | 59 | </qandaentry> |
60 | 60 | <qandaentry xml:id="faq.passwords.bestpractice"> |
61 | 61 | <question> |
62 | | - <para> |
| 62 | + <simpara> |
63 | 63 | よく使われるハッシュ関数では不適切だというのなら、 |
64 | 64 | パスワードをどうやってハッシュすればいいのですか? |
65 | | - </para> |
| 65 | + </simpara> |
66 | 66 | </question> |
67 | 67 | <answer> |
68 | | - <para> |
| 68 | + <simpara> |
69 | 69 | パスワードをハッシュするときに検討すべき重要な二点は、 |
70 | 70 | その計算量とソルトです。 |
71 | 71 | ハッシュアルゴリズムの計算コストが増えれば増えるほど、 |
72 | 72 | ブルートフォースによる出力の解析に時間を要するようになります。 |
73 | | - </para> |
74 | | - <para> |
| 73 | + </simpara> |
| 74 | + <simpara> |
75 | 75 | PHP には |
76 | 76 | <link linkend="book.password">ネイティブのパスワードハッシュ API</link> |
77 | 77 | が用意されており、これを使えば <link linkend="function.password-hash">ハッシュの計算</link> |
78 | 78 | や <link linkend="function.password-verify">パスワードの検証</link> |
79 | 79 | を安全に行えます。 |
80 | | - </para> |
81 | | - <!-- TODO Drop mention of crypt? --> |
82 | | - <para> |
83 | | - それ以外には、<function>crypt</function> 関数を使う方法もあります。 |
84 | | - この関数は、いくつかのハッシュアルゴリズムに対応しています。 |
85 | | - この関数を使うときには、指定したアルゴリズムが使えるかどうかを気にする必要はありません。 |
86 | | - 各アルゴリズムが PHP の内部でネイティブに実装されているので、 |
87 | | - ご利用の OS でサポートしていないアルゴリズムでも使うことができます。 |
88 | | - </para> |
89 | | - <para> |
| 80 | + </simpara> |
| 81 | + <simpara> |
90 | 82 | パスワードをハッシュするときのおすすめのアルゴリズムは Blowfish です。 |
91 | 83 | パスワードハッシュ API でも、このアルゴリズムをデフォルトで使っています。 |
92 | 84 | というのも、このアルゴリズムは MD5 や SHA1 と比較して計算コストが高いにもかかわらず、スケーラブルだからです。 |
93 | | - </para> |
94 | | - <para> |
95 | | - <function>crypt</function> でパスワードを検証する場合は、タイミング攻撃に注意が必要です。 |
96 | | - タイミング攻撃を避けるため、処理時間が一定な文字列比較処理を使うようにしましょう。 |
97 | | - PHP の |
98 | | - <link linkend="language.operators.comparison">== 演算子や === 演算子</link> |
99 | | - も、そして <function>strcmp</function> も、文字列比較の処理時間が一定ではありません。 |
100 | | - その点 <function>password_verify</function> はこの問題を気にしなくて済むので、 |
| 85 | + </simpara> |
| 86 | + <simpara> |
| 87 | + <function>crypt</function> 関数もパスワードのハッシュに使えますが、 |
| 88 | + 他のシステムとの相互運用性を保つために使うのがおすすめです。 |
101 | 89 | 可能な限り |
102 | 90 | <link linkend="book.password">ネイティブのパスワードハッシュ API</link> |
103 | 91 | を使うようにしましょう。 |
104 | | - </para> |
| 92 | + </simpara> |
105 | 93 | </answer> |
106 | 94 | </qandaentry> |
107 | 95 | <qandaentry xml:id="faq.passwords.salt"> |
108 | 96 | <question> |
109 | | - <para> |
| 97 | + <simpara> |
110 | 98 | ソルトとは? |
111 | | - </para> |
| 99 | + </simpara> |
112 | 100 | </question> |
113 | 101 | <answer> |
114 | | - <para> |
| 102 | + <simpara> |
115 | 103 | 暗号理論におけるソルトとは、ハッシュ処理の際に追加するデータのことです。 |
116 | 104 | 事前に計算済みのハッシュとその元入力の対応表 (レインボーテーブル) |
117 | 105 | で出力を解析される可能性を減らすために利用します。 |
118 | | - </para> |
119 | | - <para> |
| 106 | + </simpara> |
| 107 | + <simpara> |
120 | 108 | 端的に言うと、ソルトとはちょっとした追加データです。 |
121 | 109 | これをつけるだけで、ハッシュをクラックするのが劇的に難しくなります。 |
122 | 110 | 事前に計算済みのハッシュとその元入力を大量にまとめた表が、オンラインで多数公開されています。 |
123 | 111 | ソルトを使えば、そのハッシュ値がこれらの表に含まれている可能性を大きく減らすことができます。 |
124 | | - </para> |
125 | | - <para> |
| 112 | + </simpara> |
| 113 | + <simpara> |
126 | 114 | <function>password_hash</function> は、ソルトを指定しなかった場合にはランダムなソルトを作ります。 |
127 | 115 | 一般に、これがいちばんお手軽で安全なアプローチでしょう。 |
128 | | - </para> |
| 116 | + </simpara> |
129 | 117 | </answer> |
130 | 118 | </qandaentry> |
131 | 119 | <qandaentry xml:id="faq.password.storing-salts"> |
132 | 120 | <question> |
133 | | - <para> |
| 121 | + <simpara> |
134 | 122 | ソルトはどのように保存すればいいのですか? |
135 | | - </para> |
| 123 | + </simpara> |
136 | 124 | </question> |
137 | 125 | <answer> |
138 | | - <para> |
| 126 | + <simpara> |
139 | 127 | <function>password_hash</function> や |
140 | 128 | <function>crypt</function> を使った場合、戻り値であるパスワードハッシュの中にソルトが含まれています。 |
141 | 129 | このソルトは、そのままの形式でデータベースに格納する必要があります。 |
142 | 130 | というのも、利用したハッシュ関数の情報がそこに含まれており、それを直接 |
143 | 131 | <function>password_verify</function> や <function>crypt</function> |
144 | 132 | に渡せばパスワードの検証ができるからです。 |
145 | | - </para> |
146 | | - <para> |
| 133 | + </simpara> |
| 134 | + <warning> |
| 135 | + <simpara> |
| 136 | + タイミング攻撃を避けるために、保存されたハッシュ結果を比較したり |
| 137 | + 再ハッシュを行う代わりに |
| 138 | + 常に <function>password_verify</function> を使うべきです。 |
| 139 | + </simpara> |
| 140 | + </warning> |
| 141 | + <simpara> |
147 | 142 | <function>crypt</function> や <function>password_hash</function> |
148 | 143 | の戻り値の書式を次の図に示します。 |
149 | 144 | このように、使ったアルゴリズムや検証時に必要なソフトに関する情報もすべて含まれています。 |
150 | | - </para> |
| 145 | + </simpara> |
151 | 146 | <para> |
152 | 147 | <mediaobject> |
153 | 148 | <alt> |
|
0 commit comments