見出し画像

【開発者向け】パスワード保存と認証の基礎知識

対象読者

当記事はシステムの開発者向けの内容です。ユーザー視点の内容は扱っていませんので、どんなパスワードにすれば忘れず安全に管理できるかを知りたい方は別な記事をお探しください。シニアエンジニアにとっては常識レベルな内容かと思いますので、駆け出しを一歩抜けたくらいのジュニアエンジニア向けです。

伝えたいこと

当記事の目的としてはリテラシーを高めたいです。アルゴリズムや手法の種類などの技術面は深掘りせず、平文、暗号化、ハッシュ化のざっくりとした考え方から、ワンタイムパスワードや別デバイスを用いた2段階認証について触れていきます。

令和も4年に入った今日このごろ。パスワードを無加工でそのままDBに保存しているシステムなんて存在しませんよね?

要件で明示されていないからセキュリティは考えなくていい

……なんて話はありえません。発注者のリテラシーが高くないならば開発者が安全安心な仕組みを提案し牽引していくことで、より良いシステムを作り上げたいところです。そうしなければユーザーが不利益を被るだけでなく、サービスを提供している事業会社や開発者も信頼を失い、大きな損失となってしまうでしょう。三方悪しですね。

基礎知識

平文とは

「ひらぶん」と読みます。
入力された文字列そのままの無加工の状態を指します。

暗号化とは

対象の文字列を一定のルールに従って加工し、暗号にすることです。

暗号化の対義語は復号です。
暗号化した文字列は復号することで元の文字列を得られます。

暗号化:平文を暗号にする処理のこと
暗号、暗号文:暗号化された後の情報
復号:暗号文を平文に復元する処理のこと

ハッシュ化とは

対象の文字列を一定のルールに従って加工し、ハッシュ値にすることです。
パスワードはハッシュ値での保存が推奨されています。今のところ。
ハッシュ化の特徴はハッシュ値から元の文字列を得られない点です。これは暗号化と異なる点です。

で、平文の何が悪い?どうすればいいの?

前提:情報というものは常に悪意にさらされているものと考えましょう。情報を抜き取ろうとする攻撃を常にあらゆる方向から受けるものと思っておけば間違いありません。それがWebアプリのように外部とつながっていなくとも。

Q.Webでなければ攻撃を受けないのでは?

A.甘いです。

この記事をご覧ください。

「ここで注目すべきは、3つのうち2つが内部関係者の犯行によるものだという点です。実は現在、情報漏えい事件の多くで組織内部者が関与していることが分かっています。しかも、特に日本はその比率が高い傾向にあります。組織内部者による組織犯罪・不正を調べたある調査※1では、グローバルで52%、アジア太平洋で60%なのに対し、日本では72%に上るというデータが出ているのです」

日経XTECH 情報セキュリティ戦略セミナー 日本では72%が組織内部者による不正

この72%という数値が的確かどうかについては私の得られる情報では判断ができません。しかし、一定数は内部の人間による犯行であることは想像に難くありません。
おそらく多くのシステムで、パスワードはログインIDとともに1レコードでDBに保存されていることでしょう。読める状態になっていることで魔が差してしまう人がいる可能性も否定できません。
※私自身も過去に携わったあるシステムに未だに管理者権限でアクセスできそうな気がしています。やりませんけど。

平文は百害あって一利なし

Q.暗号化とハッシュ化の違いは?どっちがいいの?

A.ハッシュ化一択です。

暗号化とハッシュ化の大きな違いは復号可能かどうかです。加工後の文字列から加工前の文字列を得られるかどうか。たとえ暗号化していても内部犯が復号方法を知ることが可能ならば、それは平文で保存しているのと大差ありません。

ここで必要な考え方は元の情報が必要な場面があるのか?という観点です。
パスワードを暗号化していたとして、どんな場面で復号するのでしょうか。パスワードを知っていなければならないのはパスワードを設定した本人だけです。システム管理者、開発者は知っていてはいけません。本人以外の誰にも分からない状態にするためにハッシュ化をするのです。

これがもしショッピングサイトでカートに入れた商品の情報であればどうでしょうか。通信を行う二者間(ショッピングサイトと自分)では元の情報をやり取りしたい、しかし通信を盗み見ている第三者(すーぱーはっかー)には分からないようにしたい。この場面では通信の経路上においては暗号化され、ショッピングサイトと自分のところでは復号できるのが適切です。

Q.ハッシュ化前の文字列が分からなくても突合できる?

A.できます。

DBにはハッシュ値を保存しておきます。ログインの試行で入力されたパスワードもハッシュ化してハッシュ値同士で突合するのです。
[IPA セキュア・プログラミング講座]

Q.パスワード忘れちゃったら元に戻せないと困るのでは?

A.新しいパスワードを設定しなおすフローで対応されています。

「忘れたから教える」ではなく、再設定する方法が主流になっていますね。とはいえ、コンピューターの計算能力の向上により「ランダムな文字列をとにかくハッシュ化してハッシュ値と合致するものを探す」という力業のゴリ押しが現実的になってきてしまったという事情があります。そもそも偶然でも一致したら通ってしまうという課題からは逃れられませんね。

ワンタイムパスワード(OTP)

偶然一致する可能性を減らせるのがワンタイムパスワード(OTP)です。認証のたびに有効期間の短い使い捨てのパスワードを発行する方式です。スマホアプリやOTP発行専用のデバイスなどがありますが、本人だけが所持しているであろうデバイスを用いるのが特徴です。サーバーで生成したOTPをデバイスに通知したり、デバイス側でOTPを発行するケースが見受けられます。
私が2010年前後にPCのネトゲ(MMO)にゴリゴリにハマっていた頃には既にOTPが普及していたように思います。当時、OTPこそが最強のセキュリティと言われていました。今でも身近なところではSlackやGitHubの2段階認証でOTPが利用されていますので、その安全性の高さは間違いないでしょう。

SlackのOTP要求
GitHubのOTP要求

googleの2段階認証

もうOTPの入力すら不要になったか!という感じですね。PCのブラウザからgoogleにログインしようとするとスマホに確認が行きます。

googleの2段階認証

デバイス側ではイエスノーの確認のみで済みます。
Q.ログインしようとしていますか?
A.いいえ/はい

Q.「2段階」認証って2要素認証とは別もの?

A.別ものです。

認証の3要素というものがあります。

・記憶
・所持
・バイオメトリクス情報

IPA オンライン本人認証方式の実態調査報告書

この3要素の中から2つ使うのが2要素認証、3つ使うなら3要素認証です。

2段階認証は「二つの段階を経て認証を行う」ことを指します。
1.IDとパスワードを入力して「次へ」
2.OTPを入力して「ログイン」

パスワードは「記憶」、OTPは「所持」の要素なので、この認証方式は2要素認証であり2段階認証でもあると言えます。

「所持」は手間がかかったり紛失や盗難のリスクが捨てきれないためでしょうか、バイオメトリクス情報による認証(生体認証)を利用するサービスが増えている印象です。

3要素全部使って多段階認証すれば最強?いやいや、面倒くさすぎでしょう……要素や段階を増やしたところでセキュリティ強度は一定水準から伸び悩み、ユーザビリティが低下することは容易に想像できます。

まとめ:結局どうすればいいの?

  • 平文保存はダメ。絶対。

  • DBに保存するならハッシュ化する。

  • 忘れた時は再通知でなく再設定。

  • 2要素認証、2段階認証くらいやれると良い。

Q.ハッシュ化ってどうやるの?
A.各言語にハッシュ化のライブラリくらいあるじゃろ。ぐぐれ。

もし、もし仮に平文保存している現場があるとしたら……
実装も運用も変わるので反対派を説得するのが最大の難所だと思いますね。

この記事が気に入ったらサポートをしてみませんか?