37
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ブラウザでMFA認証

Posted at

この記事について

MFA認証はご存知でしょうか。Multi-Factor Authenticationのことで日本語でいうと「多要素認証」となります。IDとパスワードだけなんてセキュアじゃない!記憶に基づいた認証と、本人しか持ち得ない何かを持っていることなど、多数の要素に基づいて認証しようじゃないか!ということだと思いますたぶん。

正確な用語定義はおいといて、MFA認証といえばAWSのマネジメントコンソールにログインする際に有効にしている方も多いのではないでしょうか。私も有効にしています。

最初に書いたように、AWSのMFAは「IDとパスワード」と「認証コードを生成するデバイスの所有」を認証要素として採用しています。つまり別途物理的なデバイスが必要になります。多くの方はスマートフォンにGoogle Authenticatorなどの認証コード生成アプリケーションをインストールしてスマフォを「仮想デバイス」として扱っていると思います。

それでもいいのですが、自社オフィス内でログインの度にスマフォを出したりしまったりして、認証アプリをいちいち起動するのもめんどくさいです。そもそも専用デバイスもスマフォも支給されてないので、MFA認証使えない…って方もいると思います。

「PCのブラウザで表示できればいいのになあ」と思ったことはないでしょうか?私も思いました。そして作りました。JavaScriptで。この記事はそのJavaScriptライブラリとそれを使ったWebページアプリケーションの紹介となります。

AWSのMFA認証コード

こちらのドキュメントにも書いてあるように、TOTPです。RFC 6238で仕様化されているので誰でも実装できます。

TOTPは一定時間ごとに変化するHOTP(RFC 4226)です。HOTPはHMAC-based One-Time Password algorithmのことで、HMAC-SHA-1を使ってます。つまり、HMAC(RFC 2104)SHA1(RFC 3174)です。

上記の仕様を全て実装すれば認証コードが生成できます。
幸いなことにJavaScriptではcrypto-jsというライブラリがあったり、Web Crypto APIが標準化されていたりする(のかな?大体のブラウザで実装されてる)のでそれらを使えばHMAC-SHA-1は自前で実装せずとも大丈夫です、が紹介するライブラリはそれらを一切使っていません。理由は、何かに依存するというのはセキュリティ的にちょっとどうなんだろうということと、後者は非同期APIなので使いたくありませんでした1。なんで最近の仕様ではなんでもかんでもPromise返すんでしょうね。シングルスレッドで動作するんだからブロックなんてしてられない、ってのはわかるんですがそれにしてもハッシュするくらいねえ…。使い辛くてしょうがない。

JavaScriptライブラリとアプリ

愚痴を漏らしてしまいましたが、ライブラリとそれを使ったアプリの紹介です。

  • blirhotp HOTP実装。
  • browsertotp blirhotpを使いTOTPを実装したHTML+JavaScript。Google Authenticatorみたいなアプリ。
  • ngtotp browsertotpのAngularJSによる実装版。

ライブラリではHOTPまでを実装してます。アプリケーション側で30秒ごとに値を更新してTOTPを実現しています。勉強目的でAngularJS版も作ったのですが、どうも初回のアニメーションがうまく表示されません。AngularJS難しいですね…。

ではアプリケーションの使い方です。browsertotpの画面で説明します。
browsertotpのGitHub Pagesをブラウザで開いてみてください。

bh1.png

まだ何も登録していないので30秒で空になるメーターが動いてるだけです。
せっかくなのでここにAWSのIAMユーザーを登録してみましょう。

AWSマネジメントコンソールからIAMユーザーの認証情報を開いて、「MFAデバイスの管理」ボタンを押します。
aws1.png

ダイアログが表示されるので「仮想MFAデバイス」を選択して次へ。
aws2.png

確認メッセージが表示される場合がありますが、次へ。
aws3.png

QRコードのあるダイアログが表示されるので、「シークレット設定キーを表示」を選択して設定キーをコピーします。
aws4.png

browsertotpに戻り、右上または右下の+マークを押して、登録ダイアログを表示します。
そしてNameにわかりやすい好きな名前(IAMユーザー名など)、Keyに先ほどコピーした設定キーをペーストし、okボタンを押します。
bh2.png

登録が完了し、認証コードが表示されます。
bh3.png

AWSの方に戻ってbrowsertotpに表示される認証コードを2連続分認証コード1と認証コード2に入力し、「仮想MFAの有効化」ボタンを押します。
aws5.png

認証コードが正しければ完了です。
aws6.png

以降はbrowsertotpが生成したコードをMFA認証に使用してください。
aws7.png

鍵を登録して大丈夫なの?

ブラウザなんかに入力して、鍵がサーバに送信されないのか?と思われるでしょうが、送信されません。大丈夫です。HTTP通信上にも鍵データは出現しませんので盗聴もされません。紹介したアプリケーションは、HTMLとJavaScriptの静的コンテンツです。処理はクライアント側(ブラウザ内)のみで完結します。鍵(設定キー)データはどこに保存されているかというと、ブラウザのLocal Storageに保存されています。よって同一オリジンからしかデータは参照できません。

もちろんGitHub Pagesのものをそのまま利用すると、私の組織アカウントのオリジンからは鍵データにアクセスできてしまいますが、妙な処理を入れてデータを収集しないことを誓います。

ただし、当アプリケーションはMITライセンスに基づき、何らの保証もなく提供されます。GitHubページのものはデモとして試し、実際に使う場合はgit cloneしてLAN内のWebサーバで公開するのがいいでしょう。静的コンテンツなので簡単です。
ライブラリ、アプリケーションともMITライセンスですので、ご自由に修正などしていただいて構いません。

一方、git cloneしてfileスキーム(file://)で動作させるのはお勧めしません。他のfileスキームで動作するページからデータが参照できてしまいます。いや、変なものを動かしてないから大丈夫だ!と思っても、ちょっとしたJavaScriptの処理をテストする際にLocal Storageのデータを全部消しちゃったとかもありますからね。

では、素敵なMFA体験を!


  1. なんだかんだいってただ自分で実装したかっただけです。アプリの方はAngularJSやSortableをありがたく使わせてもらっています。非同期APIが使い辛いというのは本当です。

37
43
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?