聞けないハッシュ化2021/02/16に公開・約2,900字ツイートSecurity#ハッシュ化techはじめに今回はハッシュ化について紹介したいと思います。ようにふわっと理解している方もいるのではないでしょうか。ハッシュ化とはハッシュ化とは、元になるデータ(文字列)からハッシュ(あるいはハッシュ値)と呼ばれる文字列に不可逆変換することを指します。ハッシュ化を行う関数をハッシュ関数と呼びます。ハッシュ関数にもいくつか種類があり、有名どころだとMD5やSHA-256,SHA-512,bcryptなどがあります。用途としては後述の「パスワード」に関するものが多いですが、近年ではビットコインなどに用いられるブロックチェーンの分野でも扱われています。ログイン機能を持ったサービスやアプリケーションでは、データベースにパスワードを保持しておき、ログイン時にユーザが入力したパスワードが正しいものかどうかを照合する必要があります。その際にパスワードを元の文字列(平文)のまま保持しておくと、漏洩した場合などに大きなリスクとなります。その際に「パスワードをハッシュ化した値」を保持しておくことで、漏洩した場合もパスワードの平文が流出することを避けることができます。パスワードを突合する際は、「入力されたパスワードの平文から生成したハッシュ値」と「データベースに格納されているハッシュ値」を比較します。暗号化との違い文脈として「ハッシュ化」と「暗号化」が混同されたような使い方をされることがありますが、両者は別物です。暗号化は可逆変換なので、「元のデータに戻すことができる」という特性があります。対してハッシュ化は不可逆変換なので、「ハッシュ値から元の値に戻すことはできない」です。上記のような特性があるため、パスワードの管理などに用いられるハッシュ化ですが、万能というわけではありません。不可逆変換とはいっても、入力された値に対して出力されるハッシュ値は定まっているため、以下のように対応表を作ることで元の値を推測できてしまいます。...これは一般に「レインボーテーブル」と呼ばれる攻撃手法です。いった攻撃手法に対応すべく、ハッシュ化にはいくつかの工夫がされるのが一般的です。ソルトSalt(ソルト)はハッシュ化される前の文字列(平文)に付随される任意の文字列です。いう状態にすることができます。することで先のレインボーテーブル上にpasswordやadminといったよく使われるパスワードの平文とハッシュ値があったとしても、実際のパスワードの推測がしにくくなります。ペッパーSaltはその性質上、ハッシュ値と対応して管理されていることが多いです。上記の例でいうところの、「パスワードのハッシュ値」と「ユーザID」はおそらく同じテーブルで管理されていることでしょう。データが漏洩する場合、これらの値は同時に漏洩されることがほとんどのため、別な管理体系でSaltのような値を保持しているとより堅牢な仕組みになります。それがPepper(ペッパーもしくはシークレットソルト)と呼ばれるものです。Pepperはハッシュ化される文字列(平文)に付随される固定の文字列です。Saltが平文ごとに異なるのに対してPepperは全ての平文に対して共通の値になります。そのためデータベースに保持しておく必要がなく、アプリケーションの設定ファイルなどに組み込まれていることが多いです。SaltとPepperを組み合わせることでデータの漏洩に対してより強い仕組みとなります。ストレッチングストレッチングは「平文」をハッシュ化してできた「ハッシュ値A」を再度ハッシュ化して「ハッシュ値B」を生成するように、複数回のハッシュ化を行うことです。ストレッチングの回数を増やせば増やすほどレインボーテーブルを作成するのが困難になるため、ストレッチング回数は多い方が望ましいですが、その分処理のコストが嵩みます。※一般的に10000回のストレッチングが推奨されているようです。以下、ハッシュ化に関する補足的な知識です。パスワードの管理に向かないハッシュ関数があるハッシュ関数やアルゴリズムには有名無名さまざまなものがありますが、中にはパスワードの管理などには向かないものもあります。なってしまうためです。呼ばれるもので、近年有名なものでは2017年にGoogleがSHA-1の衝突を発表しました。https://security.googleblog.com/2017/02/announcing-first-sha1-collision.htmlまとめ今回は「ハッシュ化」および「ハッシュ値」について紹介しました。普段何気なく行っているログインなどの裏側で利用されており、非常に身近な技術になります。セキュリティの分野で仕事をされている方には比較的馴染みがありますが、自分自身普段はフロントエンドを中心に扱っているため、知っているようで知らないというのが正直なところでした。記事にすることで体系的にまとめられたので、備忘録としても役立つのではないかなと思います。今回は実装には触れませんでしたが、いずれJavascriptやTypescriptで主要なハッシュ関数を用いた実装を紹介したいと思います。ツイートnekoniki1992生。静岡で細々とSEやってるフロントエンジニアです。AWS/JS/TS/React/ReactNative/Python/C#バッジを贈って著者を応援しようバッジを受け取った著者にはZennから現金やAmazonギフト券が還元されます。約2,900字nekoniki1992生。静岡で細々とSEやってるフロントエンジニアです。AWS/JS/TS/React/ReactNative/Python/C#バッジを贈るバッジを贈るとは?目次はじめにハッシュ化とはどんな時に使うか暗号化との違い脆弱性と対策ソルトペッパーストレッチング豆知識パスワードの管理に向かないハッシュ関数がある平文とハッシュ値は完全に1対1ではないまとめZennエンジニアのための情報共有コミュニティAboutZennについて運営会社お知らせ・リリースGuides使い方Publicationよくある質問LinksTwitterGitHubメディアキットLegal利用規約プライバシーポリシ。