【Laravel(PHP)】で2段階認証。出来る事やセキュアなログインをまとめてみる

【Laravel(PHP)】で2段階認証。出来る事やセキュアなログインをまとめてみる

【Laravel(PHP)】で2段階認証。出来る事をまとめてみる

最近「顧客情報などを不正に抜き取られた問題で…」なんてニュースが多くあります。
その際に必ず出てくるのが「2段階認証などセキュリティー対策が万全ではなかった」というお話。

かく言う私もシステムのお仕事で「2段階認証」についてご相談を受けまして下調べをしました。
2段階認証ってそんなに万全なもの?という点を含めその結果をまとめてみます。

クラウドシステムで2段階認証を実装する事は可能か

答えは【可能】です。

まだ実装をしているわけではないのでスクリプトは記載できませんが次の2つの技術で実装できそうです。

  1. ヘッドレスブラウザ利用
  2. Google messageの利用

2段階認証の相談が増えている理由

テレビなどでQR決済を利用した『銀行口座からの現金引き出し』が話題となりました。
その時に「改善策として2段階認証によるセキュリティーの強化など…」と言うフレーズが多く露出。
これが2段階認証を【安全/安心のセキュリティ】というイメージに固定したのだと思います。

実際に2段階認証は強いセキュリティ対策なのか

実はそうでもありません。要は『使い方』です。
例を挙げてみます。

  • 1段階ログインでユーザー名+パスワードでログイン
  • 1段階目を突破できた場合、2段階目のログインページにJUMP
  • 2段階目の認証キーがPCメールに送信
  • 認証キーは4桁の数字で固定
  • 認証キーは24時間生きている
  • 2段階認証は何回間違えてもブロックされない

どうでしょう。

1段階目が突破できた事は2段階目のページが表示されたか否かで検知する事が出来ます。
2段階目のページが検知出来たら、4桁の数字を0000から順にテキストボックスに入れてログインを試みます。
多分、2段階目は3分もかからずに突破できると思います。

じゃぁ、こんなのは?
最後だけ変えてみます。

  • 2段階認証は何回間違えてもブロックされない
  • 2段階認証は3回間違えると新しい認証キーが発行されて古いキーは使えなくなる

4桁の数字の羅列は 10の4乗で10,000通り存在します。
この中から3回で間違いのない組合せを取り出すことはまず不可能でしょう。

でもやり直しが出来る。
ループ処理で番号発行したものがHITしないとは言い切れません。

2段階認証でメールアドレスに飛ばすのはセキュリティーが甘い?

その様に言われています。
理由はメールアドレスの使い方と設定されているパスワード、サーバーへの認証回数など様々な要因からです。

例えば、今はPCとスマホ両方で受信する方が増えました。
この場合、受信メールをサーバーに残してコピーをダウンロードする設定にしている事がほとんどだと思います。
そして、今はWEBメーラーを積んでいるプロバイダも多く出てきています。
メールアドレスを知っていて、WEBメーラーでログイン試行を繰返せば簡単なパスワードは突破できる可能性が高くなります。

認証コードを登録されている携帯番号にSMSで飛ばす

これは他人がログインした時に登録携帯にて確認させると言う点がとても重要です。
理由は「不正ログインを検知する仕組み」として非常に有効だからです。

ご相談を頂いたのもこの「認証キーをSMSで飛ばせないか」という内容でした。

PCからSMSを送信する方法

調べてみると方法あるんですね。
一昔前はそういうサービスをしている会社さんに頼まなきゃ出来ない仕組みだったんですけど。

具体的には『Google message』と言うサービスが最も有効だと思われます。
自分の為にも参考サイトを5つほど登録しておきます。

GoogelさんのサービスだとAPIも持ってそうな気がするのですが、そこまではまだ調べていません。
でも、ブラウザ経由で操作できるWEBサービスであると言う事は、少なくともヘッドレスChromeが使えます。
スクレイピングの要領でクリアできるって事ですね。

シングルログインは本当に甘いのか

前述の例でもわかる通り、ループ処理による合致を回避する事が重要です。
2重認証にしたからといって万全じゃないのと同じで、シングル認証だって十分にセキュリティを高められます。
シングルログインが甘いわけではありません。
結局は構築の仕方、セキュリティの段取りの仕方次第ということになります。

  • ログインパスワードは個人が自由に変更できない(システムで発行した状態から変更不可)
  • 複数回間違えたらログイン不可にする
  • ログイン可能な状態に戻す作業は管理者が手動で行う
  • ログインパスワードは定期的に自動で切り替える
  • 変更したログインパスワードはログイン後の画面/管理者画面でのみ確認が出来る

どうでしょう。
この段取りだとパスワード管理や管理者の作業が大変など運用上の課題は山積しますが認証突破は難しいでしょう。
最初の2段階認証よりはるかに高セキュリティだと思います。

セキュリティと言う1点のみで考えるとシングルログインでも十分な対策はできるわけです。

簡単なパスワードはダメと言われるけど『簡単』ってどういう基準?

今は『記号を入れて複雑に(単語にならない文字に)する』ではなく『(単純だけど)桁数を増やす』のが良いと言われています。
理由は桁数が1つ増えるだけでループの量が増えるためです。

大文字小文字を認識するとして、アルファベット+数字で62文字あります。
仮に8桁のパスワードとした場合、その組み合わせは 62の8乗 = 218,340,105,584,896 通り。
7桁だと3,521,614,606,208通りなので、桁数が1つ増えるだけで処理量が膨大になる事がよくわかります。

実は結構有効な再ログインまでの待ち時間設定

こうやって数字を書くと認証エラーから再認証可能な状態にするためのタイムラグ設定の大切さがよくわかります。

人がブラウザを操作してパスワードを間違えた場合、次のパスワードを入れるまで間違いなく1秒以上かかると思います。
これを見越して、再ログイン可能な状態にするのに1秒のタイムラグを設けるとします。
この設定で仮に4桁パスワードの全パターンを処理するとした場合、終了するまでに172日掛かります。
8桁パスワードの場合は2,527,084,555日=約6万9千年。

どんなに処理の早いPCでもログインタイムラグを施したシステムを単独で突破する事は無理でしょう。
こんな理由もあり『パスワードの桁数』がセキュリティー上で重要になってくるんです。

堅実なセキュリティ対策とは

前段で記載した通り、2段階認証を仕込んだからといって万全ではありません。

最も地道な方法は不正アクセスを監視しアク禁にする事だと思います。
私の作るシステムではいつも次のルールを仕組んでいます。

  1. アクセスIPとアクセスURLを記録(Amazon用システム開発をする際には必須です)
  2. 404エラーの出たURLを記録
  3. 404エラーのURLに閾値以上のアクセスがあった場合、このURLをブラックURLリストに追加
  4. ブラックURLリストに登録のあるURLにアクセスしてきたIPを監視対象リストに追加
  5. 監視対象リストのIPはブラックURLリストに存在するURLにアクセスする度にカウンタを1追加
  6. 監視対象リストのIPカウントが閾値以上になった場合、そのIPからのアクセスを拒否
  7. 但し、ログイン済みユーザーが行った処理については全てなかったものとする

その上で、パスワード発行の仕方とか連続ログインのタイムラグとか2段階認証とか色んなパーツを組み込む事がセキュリティの強化に大切だと思います。

まとめ

2段階認証、流行りですけど絶対ではない事に注意しましょう。