PHPカンファレンス関西 2017の発表資料です
ハッシュと暗号は違うぞ!PHPカンファレンス関西 20172017/07/15(土)13:10〜長谷川智希HASEGAWA Tomoki
View Slide
長谷川 智希デジタルサーカス株式会社 副団長CTODigital Circus, Inc. Vice-master CTOTokyo, Japan@tomzoh
ライフワーク:Web / iOSアプリ開発, ビール, 電子工作, サッカー観戦, レンタルカートレース, …長谷川 智希Web / iOS App Development, Beer, IoT,Watch soccer match, Rental Kart Racing, …デジタルサーカス株式会社 副団長CTODigital Circus, Inc. Vice-master CTOTokyo, JapanLifeworks:@tomzoh
WE ARE HIRING!!Web Development withhttp://www.dgcircus.comOmotesando, Tokyo
今日のテーマハッシュと暗号は違うぞ!Today’s theme
• 実際にあったやりとり:
• 実際にあったやりとり:お客さま「セキュリティ上DBにパスワードを保存しないで。」
• 実際にあったやりとり:お客さま「セキュリティ上DBにパスワードを保存しないで。」ベンダ「ではパスワードは暗号化して保存しましょう。」
• 実際にあったやりとり:お客さま「セキュリティ上DBにパスワードを保存しないで。」ベンダ「ではパスワードは暗号化して保存しましょう。」ぼく「まって!!!!」
• 実際にあったやりとり:• 本当にそこは暗号化?ハッシュじゃなくて?お客さま「セキュリティ上DBにパスワードを保存しないで。」ベンダ「ではパスワードは暗号化して保存しましょう。」ぼく「まって!!!!」
• 実際にあったやりとり:• 本当にそこは暗号化?ハッシュじゃなくて?お客さま「セキュリティ上DBにパスワードを保存しないで。」ベンダ「ではパスワードは暗号化して保存しましょう。」ぼく「まって!!!!」• 「ハッシュと暗号化は違うぞ!」
ハッシュとは何か
ハッシュ
ハッシュハッシュ関数ハッシュ値
ハッシュ関数• 関数:
ハッシュ関数• 関数: sin(θ), cos(θ), f(x)
ハッシュ関数• 関数: sin(θ), cos(θ), f(x)• ハッシュ関数
ハッシュ関数• 関数: sin(θ), cos(θ), f(x)• データをハッシュ関数に入力するとハッシュ値が出力される。• ハッシュ関数
ハッシュ関数• 関数: sin(θ), cos(θ), f(x)• データをハッシュ関数に入力するとハッシュ値が出力される。• ハッシュ関数の例:• ハッシュ関数
ハッシュ関数• 関数: sin(θ), cos(θ), f(x)md5, sha-1, sha-512• データをハッシュ関数に入力するとハッシュ値が出力される。• ハッシュ関数の例:• ハッシュ関数
• データをハッシュ関数に入力するとハッシュ値が出力される。
• データをハッシュ関数に入力するとハッシュ値が出力される。sha1
• データをハッシュ関数に入力するとハッシュ値が出力される。PHPカンファレンス関西sha1
• データをハッシュ関数に入力するとハッシュ値が出力される。e35257f41406f46cf884ac9c6af27707bf5c5d05PHPカンファレンス関西sha1
ハッシュ関数の特徴
ハッシュ関数の特徴1. 任意長のデータから固定長のハッシュ値を出力する2. 同じデータからは同じハッシュ値を出力する3. 別のデータからはだいたい別のハッシュ値を出力する4. ハッシュ値から元のデータを算出することはほぼ出来ない
任意長のデータから固定長のハッシュ値を出力する
任意長のデータから固定長のハッシュ値を出力するsha1
任意長のデータから固定長のハッシュ値を出力するPHPカンファレンス関西sha1
任意長のデータから固定長のハッシュ値を出力するe35257f41406f46cf884ac9c6af27707bf5c5d05PHPカンファレンス関西sha1
任意長のデータから固定長のハッシュ値を出力するe35257f41406f46cf884ac9c6af27707bf5c5d05PHPカンファレンス関西sha131bytes
任意長のデータから固定長のハッシュ値を出力するe35257f41406f46cf884ac9c6af27707bf5c5d05PHPカンファレンス関西sha131bytes160bits
吾輩は猫である…ありがたいありがたい。sha1任意長のデータから固定長のハッシュ値を出力する
吾輩は猫である…ありがたいありがたい。sha1275kbytes任意長のデータから固定長のハッシュ値を出力する
beb2bc58c7cac6510ce0638a4e8ae3f05e51b60c吾輩は猫である…ありがたいありがたい。sha1275kbytes任意長のデータから固定長のハッシュ値を出力する
beb2bc58c7cac6510ce0638a4e8ae3f05e51b60c吾輩は猫である…ありがたいありがたい。sha1275kbytes160bits任意長のデータから固定長のハッシュ値を出力する
同じデータからは同じハッシュ値を出力する
同じデータからは同じハッシュ値を出力するsha1
同じデータからは同じハッシュ値を出力するsha186f7…67b8データ1
同じデータからは同じハッシュ値を出力するsha186f7…67b8 86f7…67b8データ1 データ1
同じデータからは同じハッシュ値を出力するsha186f7…67b8 86f7…67b8 86f7…67b8データ1 データ1 データ1
別のデータからはだいたい別のハッシュ値を出力する
別のデータからはだいたい別のハッシュ値を出力するsha1
別のデータからはだいたい別のハッシュ値を出力するsha186f7…67b8データ1
別のデータからはだいたい別のハッシュ値を出力するsha186f7…67b8 e9d71…8f98データ1 データ2
別のデータからはだいたい別のハッシュ値を出力するsha186f7…67b8 e9d71…8f98 84a5…dbb4データ1 データ2 データ3
ハッシュ値から元のデータを算出することはほぼ出来ない
ハッシュ値から元のデータを算出することはほぼ出来ないsha1
ハッシュ値から元のデータを算出することはほぼ出来ないsha1データ1
ハッシュ値から元のデータを算出することはほぼ出来ないsha1データ186f7e437faa5a7fce15d1ddcb9eaeaea377667b8
ハッシュ値から元のデータを算出することはほぼ出来ないsha1データ186f7e437faa5a7fce15d1ddcb9eaeaea377667b8データ1
ハッシュ関数の利用
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」Web Site
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイルWeb Site
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site配布ファイルからハッシュ値を計算
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b8配布ファイルとsha1をWebにアップ
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b8
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b8
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b8配布ファイルをダウンロード
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b886f7…67b8sha1ダウンロードしたファイルからハッシュ値を計算
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b886f7…67b8sha1ハッシュ値を比較
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」配布ファイル86f7…67b8sha1Web Site86f7…67b886f7…67b8sha1ハッシュ値を比較「ハッシュ値が同一」 →「ちゃんとダウンロードできた」
UbuntuのISO配布サイト
UbuntuのISO配布サイトc94d54942a2954cf852884d656224186 *ubuntu-16.04-desktop-amd64.iso610c4a399df39a78866f9236b8c658da *ubuntu-16.04-desktop-i386.iso23e97cd5d4145d4105fbf29878534049 *ubuntu-16.04-server-amd64.img23e97cd5d4145d4105fbf29878534049 *ubuntu-16.04-server-amd64.iso494c03028524dff2de5c41a800674692 *ubuntu-16.04-server-i386.img494c03028524dff2de5c41a800674692 *ubuntu-16.04-server-i386.iso17643c29e3c4609818f26becf76d29a3 *ubuntu-16.04.1-desktop-amd64.iso9e4e30c37c99b4e029b4bfc2ee93eec2 *ubuntu-16.04.1-desktop-i386.isod2d939ca0e65816790375f6826e4032f *ubuntu-16.04.1-server-amd64.imgd2d939ca0e65816790375f6826e4032f *ubuntu-16.04.1-server-amd64.iso455206c599c25d6a576ba23ca906741a *ubuntu-16.04.1-server-i386.img455206c599c25d6a576ba23ca906741a *ubuntu-16.04.1-server-i386.iso
推測しにくいURLの生成「/user/1とか、IDがURLに丸見えなの、カッコ 悪いな…」 id username …1 bob …2 jones …: : : …https://example.com/user/1
推測しにくいURLの生成「/user/1とか、IDがURLに丸見えなの、カッコ 悪いな…」 id username hash …1 bob 4818…920a …2 jones 4c46…3902 …: : : …https://example.com/user/4c46bc790ffe655a1e65acfacf95da50cd4d3902
ログインパスワードの保存よくあるログインのフローはこんな:• ユーザはユーザ名とパスワードを入力• システムはDBからユーザ名でレコードを探す• 見つけたレコードのパスワードと 入力されたパスワードが一致すればログインOK!
usernamepasswordbob●●●Login
id username password …1 bob M2teM2P0 …2 jones tqigg75Y …: : : … usernamepasswordbob●●●Login
id username password …1 bob M2teM2P0 …2 jones tqigg75Y …: : : … usernamepasswordbob●●●Login入力されたパスワードとDBのパスワードを比較
id username password …1 bob M2teM2P0 …2 jones tqigg75Y …: : : … usernamepasswordbob●●●Login入力されたパスワードとDBのパスワードを比較入力されたパスワードとDBのパスワードが一致 → ログイン成功
「パスワードをDBにそのまま保存するの 怖いなあ…」 id username password …1 bob M2teM2P0 …2 jones tqigg75Y …: : : …
「パスワードをDBにそのまま保存するの 怖いなあ…」「ユーザ登録時にユーザが設定した文字列と、 ログイン時にユーザが入力した文字列が 同じものだと判断できればいいんだよね。」
「パスワードそのものじゃなくて、 パスワードのハッシュ値を保存しておこう!」
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : …「パスワードそのものじゃなくて、 パスワードのハッシュ値を保存しておこう!」パスワードのハッシュ値
usernamepasswordbob●●●Signup
usernamepasswordbob●●●Signup入力されたパスワードをハッシュ化3c65…1d8bsha1
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : … usernamepasswordbob●●●Signup3c65…1d8bsha1DBにはハッシュ化されたパスワードを保存
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : … usernamepasswordbob●●●Login
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : … usernamepasswordbob●●●Login入力されたパスワードをハッシュ化3c65…1d8bsha1
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : … usernamepasswordbob●●●Login3c65…1d8bsha1入力されたパスワードをハッシュ化したものとDBに保存されたものを比較
id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : … usernamepasswordbob●●●Login入力されたパスワードをハッシュ化したものとDBに保存されたハッシュ化したパスワードが一致→ ログイン成功3c65…1d8bsha1入力されたパスワードをハッシュ化したものとDBに保存されたものを比較
DBにパスワードそのものが保存されている必要は無い
ログイン処理にパスワードそのものが必要な訳でも無い
ハッシュ化されたパスワードがあれば良い。(もとに戻せなくても)
ハッシュ、便利ですね!
ハッシュ値の衝突
元データ 32bitdata 1data 2data 3data 4data 5ハッシュ値 2bithash 1hash 2hash 3hash 4sha-beer
元データ 32bitdata 1data 2data 3data 4data 5ハッシュ値 2bithash 1hash 2hash 3hash 4sha-beer任意長のデータから2bitのハッシュ値を出力する
元データ 32bitdata 1data 2data 3data 4data 5ハッシュ値 2bithash 1hash 2hash 3hash 4sha-beer4,294,967,296通り任意長のデータから2bitのハッシュ値を出力する
元データ 32bitdata 1data 2data 3data 4data 5ハッシュ値 2bithash 1hash 2hash 3hash 44通りsha-beer4,294,967,296通り任意長のデータから2bitのハッシュ値を出力する
元データ 32bitdata 1data 2data 3data 4data 5ハッシュ値 2bithash 1hash 2hash 3hash 4sha-beer衝突!任意長のデータから2bitのハッシュ値を出力する
ハッシュ値の衝突• ハッシュ値は必ず衝突する
ハッシュ値の衝突• ハッシュ値は必ず衝突する• ハッシュを使う場合は衝突したら困るか困らないかを 必ず考える。
ハッシュ値の衝突• ハッシュ値は必ず衝突する• ハッシュを使う場合は衝突したら困るか困らないかを 必ず考える。• 推測しにくいURLの生成の例:
ハッシュ値の衝突• ハッシュ値は必ず衝突する• ハッシュを使う場合は衝突したら困るか困らないかを 必ず考える。• 推測しにくいURLの生成の例: 衝突したら困る
ハッシュ値の衝突• ハッシュ値は必ず衝突する• ハッシュを使う場合は衝突したら困るか困らないかを 必ず考える。• 推測しにくいURLの生成の例: 衝突したら困る• ログインパスワードの保存:
ハッシュ値の衝突• ハッシュ値は必ず衝突する• ハッシュを使う場合は衝突したら困るか困らないかを 必ず考える。• 推測しにくいURLの生成の例: 衝突したら困る• ログインパスワードの保存: 衝突しても困らない
「ハッシュ値の衝突」による攻撃
ファイルの同一性チェック「ダウンロードしてきたファイル、 ちゃんとダウンロードできたかな…」86f7…67b8sha1Web Site86f7…67b886f7…67b8sha1「ハッシュ値が同一」 →「ちゃんとダウンロードできた」
ハッシュ値衝突による攻撃 神ソフトができたので公開するよ。ハッシュ値付きね。
ハッシュ値衝突による攻撃 神ソフトができたので公開するよ。ハッシュ値付きね。ウィルス入れて…。末尾にゴミデータ付け加えてハッシュ値同じにしてミラーサイトぽく配布。
ハッシュ値衝突による攻撃 ミラーサイトからダウンロードしたファイル、大丈夫かな?…ハッシュ値合ってるしOK! 神ソフトができたので公開するよ。ハッシュ値付きね。ウィルス入れて…。末尾にゴミデータ付け加えてハッシュ値同じにしてミラーサイトぽく配布。
ハッシュ値衝突による攻撃 ミラーサイトからダウンロードしたファイル、大丈夫かな?…ハッシュ値合ってるしOK! 神ソフトができたので公開するよ。ハッシュ値付きね。ウィルス入れて…。末尾にゴミデータ付け加えてハッシュ値同じにしてミラーサイトぽく配布。 ぎゃー!ウィルス入りだった!!!
ハッシュ値衝突による攻撃 ミラーサイトからダウンロードしたファイル、大丈夫かな?…ハッシュ値合ってるしOK! 神ソフトができたので公開するよ。ハッシュ値付きね。ウィルス入れて…。末尾にゴミデータ付け加えてハッシュ値同じにしてミラーサイトぽく配布。 ぎゃー!ウィルス入りだった!!!どうしたらよかった?
ハッシュ値衝突による攻撃の対策• どうしようもない。• ハッシュ値の衝突を意図的に起こしにくいアルゴリズムを使うしかない。
ハッシュの安全性
ハッシュ関数の特徴1. 任意長のデータから固定長のハッシュ値を出力する2. 同じデータからは同じハッシュ値を出力する3. 別のデータからはだいたい別のハッシュ値を出力する 4. ハッシュ値から元のデータを算出することはほぼ出来ない
ハッシュ関数の特徴1. 任意長のデータから固定長のハッシュ値を出力する2. 同じデータからは同じハッシュ値を出力する3. 別のデータからはだいたい別のハッシュ値を出力する 4. ハッシュ値から元のデータを算出することはほぼ出来ない= 衝突しにくい
ハッシュ関数の特徴1. 任意長のデータから固定長のハッシュ値を出力する2. 同じデータからは同じハッシュ値を出力する3. 別のデータからはだいたい別のハッシュ値を出力する 4. ハッシュ値から元のデータを算出することはほぼ出来ない= 衝突しにくい= 元のデータを算出しにくい
良いハッシュ関数の特徴原像計算困難ハッシュ値から元データを算出しにくい第2原像計算困難 (弱衝突耐性)あるデータが与えられた時に、そのデータから算出されるハッシュ値と同じハッシュ値を出力する別のデータを見つけにくい衝突困難(強衝突耐性)同じハッシュ値を出力する2つのデータを見つけにくいn
良いハッシュ関数の特徴原像計算困難ハッシュ値から元データを算出しにくい第2原像計算困難 (弱衝突耐性)あるデータが与えられた時に、そのデータから算出されるハッシュ値と同じハッシュ値を出力する別のデータを見つけにくい衝突困難(強衝突耐性)同じハッシュ値を出力する2つのデータを見つけにくい計算量: 2n計算量: 2n2
23 February, 2017
SHAttered の計算量原像計算困難ハッシュ値から元データを算出しにくい第2原像計算困難 (弱衝突耐性)あるデータが与えられた時に、そのデータから算出されるハッシュ値と同じハッシュ値を出力する別のデータを見つけにくい衝突困難(強衝突耐性)同じハッシュ値を出力する2つのデータを見つけにくい計算量: 2n
SHAttered の計算量原像計算困難ハッシュ値から元データを算出しにくい第2原像計算困難 (弱衝突耐性)あるデータが与えられた時に、そのデータから算出されるハッシュ値と同じハッシュ値を出力する別のデータを見つけにくい衝突困難(強衝突耐性)同じハッシュ値を出力する2つのデータを見つけにくい計算量: 2n1602計算量: 2 = 280
SHAttered の計算量原像計算困難ハッシュ値から元データを算出しにくい第2原像計算困難 (弱衝突耐性)あるデータが与えられた時に、そのデータから算出されるハッシュ値と同じハッシュ値を出力する別のデータを見つけにくい衝突困難(強衝突耐性)同じハッシュ値を出力する2つのデータを見つけにくい計算量: 2n計算量: 2631602計算量: 2 = 280
ハッシュを使ったシステムへの攻撃
「推測しにくいURLの生成」への攻撃
原像推測による攻撃 /user/1 ってのもアレなのでハッシュ化したろ。$url = sprintf("/user/%s", md5($userId));
原像推測による攻撃 /user/1 ってのもアレなのでハッシュ化したろ。$url = sprintf("/user/%s", md5($userId));この文字列の並び、md5だな。どうせ元は連番だろ。for ($i = 0; $i < 1000; $i++)}$page = file_get_contents( sprintf("/user/%s", md5($i)));
原像推測による攻撃 /user/1 ってのもアレなのでハッシュ化したろ。$url = sprintf("/user/%s", md5($userId));この文字列の並び、md5だな。どうせ元は連番だろ。for ($i = 0; $i < 1000; $i++)}$page = file_get_contents( sprintf("/user/%s", md5($i))); 全部バレた!
原像推測による攻撃 /user/1 ってのもアレなのでハッシュ化したろ。$url = sprintf("/user/%s", md5($userId));この文字列の並び、md5だな。どうせ元は連番だろ。for ($i = 0; $i < 1000; $i++)}$page = file_get_contents( sprintf("/user/%s", md5($i))); 全部バレた!どうしたらよかった?
原像推測による攻撃の対策• 元データがバレない様にする。
原像推測による攻撃の対策• 元データがバレない様にする。• 元データが「1」とかだからバレる。
原像推測による攻撃の対策• 元データがバレない様にする。• 元データに長い文字列(ソルト)を追加する。• 元データが「1」とかだからバレる。
原像推測による攻撃の対策• 元データがバレない様にする。• 元データに長い文字列(ソルト)を追加する。$salt = "aemi4ahcoh7weeN2euth";$url = sprintf("/user/%s", md5($salt.$userId));• 元データが「1」とかだからバレる。
原像推測による攻撃の対策• 元データがバレない様にする。• 元データに長い文字列(ソルト)を追加する。$salt = "aemi4ahcoh7weeN2euth";$url = sprintf("/user/%s", md5($salt.$userId));• 攻撃者は「aemi4ahcoh7weeN2euth1」を推測しなければならなくなる。• 「連番とかをわかりにくくする」様な用途では、ソルトを付けない形でハッシュ関数を使うことは無いと思って良い。• 元データが「1」とかだからバレる。
「ログインパスワードの保存」への攻撃
ログインパスワードの保存 id username hashed_password …1 bob 3c65…1d8b …2 jones d578…fa1f …: : : …「パスワードそのものじゃなくて、 パスワードのハッシュ値を保存しておこう!」パスワードのハッシュ値
原像計算による攻撃 パスワードをハッシュ化してDBに保存したよ。これでデータが漏洩しても大丈夫!
原像計算による攻撃 パスワードをハッシュ化してDBに保存したよ。これでデータが漏洩しても大丈夫!この文字列の並び、md5だな。計算済みの表を使って…。元データ md5abcde ab56b4d92b40713acc5af89985d4b786qwerty d8578edf8458ce06fbc5bb76a58c5ca4password 5f4dcc3b5aa765d61d8327deb882cf99: :
原像計算による攻撃 パスワードをハッシュ化してDBに保存したよ。これでデータが漏洩しても大丈夫! あっという間にパスワードがばれた!この文字列の並び、md5だな。計算済みの表を使って…。元データ md5abcde ab56b4d92b40713acc5af89985d4b786qwerty d8578edf8458ce06fbc5bb76a58c5ca4password 5f4dcc3b5aa765d61d8327deb882cf99: :
原像計算による攻撃 パスワードをハッシュ化してDBに保存したよ。これでデータが漏洩しても大丈夫! あっという間にパスワードがばれた!どうしたらよかった?この文字列の並び、md5だな。計算済みの表を使って…。元データ md5abcde ab56b4d92b40713acc5af89985d4b786qwerty d8578edf8458ce06fbc5bb76a58c5ca4password 5f4dcc3b5aa765d61d8327deb882cf99: :
原像計算による攻撃の対策• ユーザがどんなパスワードを付けても事前に用意されたテーブルにそれが現れない様にする。
原像計算による攻撃の対策• ユーザがどんなパスワードを付けても事前に用意されたテーブルにそれが現れない様にする。• そのために、元データにソルトを追加する。
原像計算による攻撃の対策• ユーザがどんなパスワードを付けても事前に用意されたテーブルにそれが現れない様にする。• そのために、元データにソルトを追加する。abcdeoMF0iyDQB8Bpsl6npJer9XTT7PNdCWug607452f4c75ee977ea169e49f6c1db1cmd5
原像計算による攻撃の対策• ユーザがどんなパスワードを付けても事前に用意されたテーブルにそれが現れない様にする。• そのために、元データにソルトを追加する。元データ md5abcde ab56b4d92b40713acc5af89985d4b786abcdeoMF0iyDQB8Bpsl6npJer9XTT7PNdCWug607452f4c75ee977ea169e49f6c1db1cmd5
原像計算による攻撃の対策• ユーザがどんなパスワードを付けても事前に用意されたテーブルにそれが現れない様にする。• そのために、元データにソルトを追加する。• 前のケースと同じ。• ハッシュと聞いたらソルトは?と思うぐらいで良い。
ハッシュと暗号
ハッシュと暗号ハッシュ関数によるハッシュ化一方向 / ハッシュ値から元データに戻せないことが前提md5, sha-1, sha-512, …n
ハッシュと暗号ハッシュ関数によるハッシュ化一方向 / ハッシュ値から元データに戻せないことが前提md5, sha-1, sha-512, …暗号化 / 復号双方向 / 暗号文から平文に戻せることが前提秘密裏に通信をすることを目的とするAES, DES, RSAn
みなさんは大丈夫だと思いますが
ハッシュも暗号化も同じ様なもんじゃない?と思ってる人は…
ハッシュでも暗号でもないでもぱっと見ハッシュに似てる概念
たぶんこれも同一視しちゃう
ハッシュと暗号と心強さと難読化一方向 / プログラムなどを読みにくくするための変換。結果としてファイルサイズが小さくなるので「圧縮」って呼んだりも。JavaScriptやJavaでよく利用される。n双方向 / エンコードされたものをデコードできることが前提。鍵の要素が無いため、アルゴリズムを知っていれば誰でも元に戻せる。urlencode(), Base64, …エンコード / デコード
正しく選択しよう!
まとめ
まとめ• ハッシュ関数はデータをハッシュ値に一方向に 変換するもの。• ハッシュ関数を使う時は必ず…• 入力データにソルトを追加する• 衝突の可能性を考慮に入れる• 暗号化、エンコード、難読化とは違う。• ハッシュや暗号を使う時は、なぜそれを使うか、 なぜその判断をすべきかを考えよう。
ThanksWE ARE HIRING@tomzohプリーズ:#phpkansai / ブログ / 懇親会
時間があれば追加エピソード
プログラミング言語の「ハッシュ」ep.1
プログラム言語の「ハッシュ」• PHPの配列は文字列をキーに使える。• 他の言語でも大抵この機能はある。• 連想配列• ハッシュ
何故「ハッシュ」?
連想配列の実装
$array[‘kagawa’] = ‘shinji’;連想配列とハッシュ
$array[‘kagawa’] = ‘shinji’;連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yuto
$array[‘kagawa’] = ‘shinji’;連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutokagawa:shinji
$array[‘kagawa’] = ‘shinji’;連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutosha-beerkagawa:shinji
$array[‘kagawa’] = ‘shinji’;連想配列とハッシュ0x02アドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutosha-beerkagawa:shinji
$array[‘kagawa’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュ0x02アドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutosha-beerkagawa:shinji
$array[‘kagawa’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュ0x02アドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutosha-beerkagawa:shinji0x1200
$array[‘kagawa’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutokagawa:shinji0x1200
echo $array[‘kagawa’];インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutokagawa:shinji0x1200
echo $array[‘kagawa’];インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutokagawa:shinji0x1200sha-beer
echo $array[‘kagawa’];インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x12000x1300 nagatomo:yutokagawa:shinji0x12000x02sha-beer
O(1)
あれ、衝突は?
もちろんあります
$array[‘okazaki’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x1200 kagawa:shinji0x1300 nagatomo:yuto0x1200
$array[‘okazaki’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x1200 kagawa:shinji0x1300 nagatomo:yuto0x1200okazaki:shinji
$array[‘okazaki’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュアドレス データ0x1000 honda:keisuke0x11000x1200 kagawa:shinji0x1300 nagatomo:yutosha-beer0x1200okazaki:shinji
$array[‘okazaki’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュ0x02アドレス データ0x1000 honda:keisuke0x11000x1200 kagawa:shinji0x1300 nagatomo:yutosha-beer0x1200okazaki:shinji
$array[‘okazaki’] = ‘shinji’;インデックス アドレス0x00 0x11000x01 0x10000x020x03 0x1300連想配列とハッシュ0x02アドレス データ0x1000 honda:keisuke0x11000x1200 kagawa:shinji0x1300 nagatomo:yutosha-beer0x1200okazaki:shinji衝突!
hashdosep.2
hashdos• PHPやRubyなどWebアプリで使用する言語では、GETやPOSTのパラメタ、Cookieを連想配列に格納してWebアプリに引き渡す。kagawashinjiSubmit
hashdos• PHPやRubyなどWebアプリで使用する言語では、GETやPOSTのパラメタ、Cookieを連想配列に格納してWebアプリに引き渡す。kagawashinjiSubmit$_POST = [‘familyName’ => ’kagawa’,‘firstName’ => ’shinji’,];
hashdos• GETやPOSTのパラメタ名、Cookie名が連想配列のキーになる。• GETやPOSTのパラメタ名、Cookie名はブラウザ側から任意に指定可能。
hashes$_POST = [‘okazaki’‘kiyotake’‘kagawa’‘honda’:‘eiji’];=> ‘shinji’,=> ‘hiroshi’,=> ‘shinji’,=> ‘keisuke’,=> ‘kawashima’,
hashes$_POST = [‘okazaki’‘kiyotake’‘kagawa’‘honda’:‘eiji’];=> ‘shinji’,=> ‘hiroshi’,=> ‘shinji’,=> ‘keisuke’,=> ‘kawashima’,外部から任意に作成可能
hashes$_POST = [‘okazaki’‘kiyotake’‘kagawa’‘honda’:‘eiji’];=> ‘shinji’,=> ‘hiroshi’,=> ‘shinji’,=> ‘keisuke’,=> ‘kawashima’,外部から任意に作成可能すべてのキーを衝突させると??
hashes$_POST = [‘okazaki’‘kiyotake’‘kagawa’‘honda’:‘eiji’];=> ‘shinji’,=> ‘hiroshi’,=> ‘shinji’,=> ‘keisuke’,=> ‘kawashima’,外部から任意に作成可能すべてのキーを衝突させると??著しくパフォーマンスが低下する
demohttp://koto.github.io/blog-kotowicz-net-examples/hashcollision/kill.html
原像計算攻撃ep.3
sha1が破られる is 一大事
sha1が破られる is 一大事ただし一定の条件下で
本当?
ハッシュ値の原像計算• ハッシュ値の原像計算の原則は総当たり• 160ビットのハッシュ値の原像計算の計算量は2^160。• 元データのパターンが少なかったら?• 携帯の番号って 0[5, 7, 9]0-[0-9]{8} ぐらいしか無い。(010もあったっけ?)• 3億通り
$salt = 'iAakR1rFT2CzRWvV';$plain = '09012345678';$hashed = sha1($salt.$plain);foreach ([5, 7, 9] as $second){for ($i = 0; $i <= 99999999; $i++){$check = sprintf("0%d0%08d", $second, $i);if (sha1($salt.$check) == $hashed){printf("Got it! Plain text is %s".PHP_EOL, $check);return;}}}
原像計算攻撃は総当たりベース
ハッシュ化されたパスワードが流出しても比較的大丈夫なのはパスワードは文字数や文字種のバリエーションが多いから。
巨人の肩に乗るep.4
「パスワードのハッシュ化」とか 難しいところはたいてい 頭いい人が考えて仕組みを作ってくれている
巨人の肩に乗ろう
ただし
中身を理解せずになんとなく使うのは最悪
意味が無いだけなら良いが、せっかく考えられた仕組みを殺すことにもなり得る
例えば…
自分は何をしたいのか「巨人」は何を与えてくれているのかちゃんと理解して、正しく使おう
そして…
この手の「特定の製品に依存しない知識」はエンジニアの血となり肉となり、エンジニアとして生きていくための力になる
「力が…欲しいか…」
こういう知識をどうやって得るか• ハッシュに限らず、ソフトウェア開発には多くの周辺知識が必要。• 情報系の大学や専門学校では教わる(はず)。• 体系的に広く学ぶのであれば資格試験が便利。• IPA(情報処理推進機構)の 「情報処理技術者試験」がおすすめ。http://www.jitec.ipa.go.jp
共通鍵暗号と公開鍵暗号ep.5
共通鍵方式暗号 信頼できない通信路信頼できる通信路
共通鍵方式暗号 信頼できない通信路信頼できる通信路鍵を事前に共有
共通鍵方式暗号 ƪ信頼できない通信路鍵を使って暗号化信頼できる通信路鍵を事前に共有
共通鍵方式暗号 ƪ ƪ信頼できない通信路鍵を使って暗号化信頼できる通信路鍵を事前に共有
共通鍵方式暗号 ƪ ƪ信頼できない通信路鍵を使って暗号化暗号化に使ったのと同じ鍵を使って復号信頼できる通信路鍵を事前に共有
公開鍵方式暗号 信頼できない通信路
公開鍵方式暗号 信頼できない通信路公開鍵を事前に共有
公開鍵方式暗号 ƪ信頼できない通信路相手の公開鍵を使って暗号化公開鍵を事前に共有
公開鍵方式暗号 ƪ ƪ信頼できない通信路相手の公開鍵を使って暗号化自分の秘密鍵を使って復号公開鍵を事前に共有
小ネタ集ep.6
妥当なソルト• ソルトとして妥当な文字列は何か• 長さが一定以上あることだけど…• 長いソルトはハッシュ関数に入力するデータの情報量を増やす。• 情報量が増えると衝突を起こしやすくなるかもしれない。• 一般的に使用されるハッシュ関数はこの様な「近いデータ(ソルトが同じで元データ部分だけが違うデータ)」が衝突しにくい様に設計されている。• 20文字程度、とか、26文字程度、とかいろいろ言われている。
encrypt / decrypt• 暗号化と復号• 暗号化 encrypt• 復号 decrypt• 日本語では「暗号」は名詞「復号」は動詞。• なので「暗号化」として動詞化する。• 英語は「encrypt」も「decrypt」も動詞。• シンプルでうらやましいね!
ハッシュテーブル• あらかじめ全ての文字列に対するハッシュ値を計算しておき、そこから検索する方法で高速に原像計算が可能。元データ md5aaaa 74b87337454200d4d33f80c4663dc5e5aaab 4c189b020ceb022e0ecc42482802e2b8aaac 3963a2ba65ac8eb1c6e2140460031925: :
ハッシュテーブル• あらかじめ全ての文字列に対するハッシュ値を計算しておき、そこから検索する方法で高速に原像計算が可能。• このテーブル、すごくデカい。• 4文字で640MB、5文字で50GB、8文字で12PB。• テーブルを小さくするためにレインボーテーブルという 方法がある。元データ md5aaaa 74b87337454200d4d33f80c4663dc5e5aaab 4c189b020ceb022e0ecc42482802e2b8aaac 3963a2ba65ac8eb1c6e2140460031925: :
告知
iOSDC Japan 2017https://iosdc.jp/2017/ チケット販売中2017.09.15(金)〜17(日)
PHPerKaigi 2018https://phperkaigi.jpスポンサー募集…するかも2018.03.10(土)• PHPerのためのカンファレンス• 東京都練馬区 Coconeriホールにて• 朝から晩までテックトーク• 夕方からはビールを飲みながら• 夜はクラフトビールで懇親会