RSAカンファレンス 2018のお薦めスライド
RSAカンファレンス2018のスライドが公開されていたので、ざっと一通りみました。 おもに私が面白い・役に立ったなと思うもののまとめをします。
オペレーション
Incident Response In the Cloud
クラウド上でSANS GCIHをするには、というテーマの発表です。Preparation, Detection, Containment, Recoveryのフェーズでの対応をクラウド向けに再構築しているもので、とても勉強になりました。
- Preparation
- Detection
- Containment
- Tag付けして調査
- 隔離VPCにいれtり、隔離SGを適用
- EC2のEBSをスナップショットする(フォレンジックEC2にアタッチする)
- メモリはMargarita Shotgunなどで取得
- SANSのInvestigative Forensic Toolkit(SIFT)の構築. EBSスナップショットをアタッチ。
- ThreatResponse Suiteを使うのも良い(AWS_IR, Incident pony, Margarita Shotgun)
- Digital Forensic Analysis of Amazon Linux EC2 Instances
- Erradication
- Terraform destroy && Terraform apply
他にも、github.com/tradichel/AWSSecurityAutomationFrameworkなどが良さそう。
From SIEM to SOC: Crossing the Cybersecurity Chasm
昔はエンドポイントはAVなどで防御だけやっておけばよかったけど、最近は防御も検知も一次対応もやらないとね、と主張したスライドはよかったです。まあ、これは従来のネットワーク上の検知を否定するものではなく、より詳細な対策をするにはエンドポイントもみていこう、という話なのでとてもまっとうな話だと思います。Carbon BlackというEDRベンダーのプレゼンなのですが、「AntiVirustは死んだ」のような脳死に営業文句がなかったのは相当ぷらすでした。
Identity
Risk-based approach to deployment of omnichannel biometrics in Sberbank
Biometricksの話です。Biometricsによる認証メソッドはすでに、ハイプ・サイクルにおける実用段階まで到達していて
ただ、欧州では可用性が低いことと偽造可能なことからBiometricsは信用されておらず、Something You Haveのカード等のSomething You Haveを採用しています。まあね〜。
そういったBiometricsにおける課題から、Riskベースの認証について、そのワークフロー、リスクスコアの計算モデル、ユースケースの取組が紹介されています。
余談ですがJuniper, TOP10 Disruptive technologies in fintechがよい読み物でした。
Adventures in OpenBaking: Understanding OAuth and OpenID Connect Client Ecosystems
Open Bank in イギリスにおける現状と課題の概要を掴むのによいです。 半分ほどのスライドがOAuth 2.0 Dynamic Client Registration(RFC 7591 )に費やされていました。Dynamic Client Registrationは、認可サーバーに対してクライアントが直接メタデータを登録することで、クライアントクレデンシャルを受け取る仕様です。 https://www.rsaconference.com/writable/presentations/file_upload/idy-r04_adventures_in_open_banking-_understanding_oauth-openid_client_ecosystems.pdf
Google And Microsoft Debut: Replacing Passwords w/ FIDO2 Authentication
FIDO2の紹介ですね。まあ、そこまで新しいことはなかったかな...が、おぬぬめです。
https://www.rsaconference.com/writable/presentations/file_upload/idy-f02_mcdowellfinal.pdf
Detection of Authentication Events involving stolen enterprise credentials
不正な認証イベントを検知するための、機械学習モデル及びインフラの考え方についての実用的なお話になるかと思います。特長としては、認証イベントの発生時間、同時間帯の端末上のイベント、通信イベント(ポート毎のパケット・バイト・接続数、DNSイベント)、同時間帯の認証側サーバーのイベントになります。これをランダムフォレスト、ロジスティック回帰、Naiive Bayes, マルチレイヤーパーセプトロン、SMOを使って学習させた模様。
特にイベントデータのストリームから、同データを抽出し、アップデートをかけていくかは参考になりました。
でも、stolen enteprise credentialsはちょっと関係なかったかな...?
OAuth2.0 Threat Landscape
RFC6819の内容ですね。下記の攻撃(脅威)および対策についてまとめたものです。
- CSRF攻撃
- Token/Code漏えい
- Token使い回し
Can blockchain enable identity management?
Portableな個人の属性を個人が選択して使い、その属性情報と信頼スコアをBlockchainに残すSelf Sovereign Identityなしくみです。最近だとMicrosoftが活発に取り組んでいる気がします。
Identity In Ten Hundred words
Identity周りにおける用語解説集です。これだけでプレゼンがなりたったかよくわかりませんが、辞書的に使うのにはよいです。
その他
Transfer Learning: Repurposing ML Alogorithms from different domains to cloud defenese.
Microsoftにおけるクアウドを防御するための機械学習に関する発表です。正直難しかったのでまとめられてませんが、悪意あるPowershellを検知する手法など興味深いかったです。
技術書典4に出店した as セキュア旅団
技術書典4にサークル名「セキュア旅団」として、新著「俺らの愛したセキュリティ」を販売しました。
お立ち寄りくださった皆様、ご購入いただいた皆様、誠にありがとうございました。万が一入手できなかった方のためにbooth(など)でダウンロード購入できるようにする予定ですので、お待ち下さい。
本投稿では、備忘録として次の2点についてまとめます。
- 執筆内容
- サークルとして取り組んだこと
執筆内容
「セキュア旅団」は自分の好きなセキュリティ技術をアウトプットしていくことを目的としています。世の中にインパクトを与えるか、インフルエンサーになるか、そういった結果は大事ではなく、ただアウトプットを至上とします。そんな「俺得」技術書を今回も書かせて頂きました。
前回の「ニッチセキュリティー明星へ登る」の著者3人チームに情シス得意マンが加わったことで、質的にもページ数的にも肉厚な技術同人誌を世に出せました。本誌は次の4章からなっています。
- PowerShellによるWin32 APIプログラミングの基礎
- 実践Metasploit API
- Beyond Corp by Google
- 相互連携する金融時代 - FAPI the Security
最初の2章はペネトレーションテスターに必須となる技術です。1章目は最近のExploitで多様されているPowerShellプログラミングの基礎です。ペネトレーションテスター向けに書かれていますが、情シスによる管理のコード化という観点からも非常に有用そうです。なお、この著者は1人で53p仕上げています。意味がわからない。怖い。
2章目はペネトレーションテスターなら一度は触ったことがあるであろうMetasploitのRPC APIの叩き方を取り上げています。Pythonクライアントを使って、効率的なペンテストをやりたいかたにはうってつけではないでしょうか。私はGolangで叩いて見ようと思いました。
そして、情シス待望の書が3章目です。みなさまの社内セキュリティはどのような環境でしょうか?USではネットワーク境界でセキュリティを担保しないゼロトラストネットワークスというアーキテクチャが主流になりつつあります。特にGoogleはそれに関する論文を「Beyond Corp」という名前で出すほど進んでおり、VPNに頼らない社内アクセスを実現しています。本章はその論文を日本語にまとめたものです。
最後の4章「相互連携する金融時代 - FAPI the Security」を私が執筆しました。まだ登場したばかりでその将来性は未知数ですが、いままで1サービス内に閉じていた金融系の経済圏をよりオープンにするにあたって策定されたFinancial API(FAPI)のRead Onlyなセキュリティ仕様を、OAuth 2.0やOIDCのrfcとともに読み解いたちょっと頑張ってしまった作品です。
この用に様々な、かつ尖ったセキュリティ技術の知識を結集させたものが、新刊「俺らの愛したセキュリティ」です。内容がわかったところで、次はどのように本著を作成から販売までしたかご説明します。
サークルとしての活動
メンバーに声をかけたのは大体1月です。しかし、私自身の転職やDroidKaigiでの講演により、本格的な方針を決定したのは2月中旬ぐらいでした。そこから各々が原稿をRe:Viewで書き、4/21にマージ・販促体制を構築し当日に臨みました。方針は次の通りです。
- 電子書籍オンリー
- ダウンロードカードによる配布
- 1000円
- 表紙担当を起用
電子書籍オンリーにしたのは、主に2つの理由があります。まだノウハウがないのに、期待値とことなる分量によって在庫リスクが発生することを恐れたを抱えたくなかったことが理由の1つです。もっと大きな理由は、ハードを準備することで圧迫されるスケジュールが大分厳しかった事です。正直、創業2年目のスタートアップに転職したてで、サークルのマネージメントに割く余力はなかったので、これはただしい判断だったと思います(そもそもマネージメント苦手です)。
ダウンロードカードを準備したのは、前回の反省からです。前回も電子書籍オンリーでしたが、QRコードを購入者に読み取ってもらう販促形式でした。これは意外と時間がかかります。それぞれのカメラの精度が異なりますし、混雑を極めている中でパラレルにさばくことは困難でした。何より①スマホを取り出す②アプリを立ち上げる③照準をあわせる④読み込む、とアクション数が多くなります。他にも、読み込んだあとなんらかの拍子にダウンロードをできなかった場合、支払った料金がむだになってしまうリスクがありました。
そういった反省から、1000円札と 交換する
形で入手できるダウンロードカードにし、これらの課題を解決しました。ただ、予想よりずっと来場者が多かったため、途中でダウンロードカードがなくなり、急いで擦りに行くという見通しの甘さを露呈してしまいました。次回のイベントに活かそうとおもいます。
また、前回は500円でしたが、今回は1000円にしました。これは価格そのものより、やはりオペレーションの観点からの改善です。基本的に1000円で支払う人が多い(という印象をもっている)技術書典で硬貨を使うと、お釣りが財布を物理的に圧迫します。
また、お釣りをわたすことはそれだけ価値交換のプロセスが多くなることだと思います。従って、人口密度の高いところではUX的に良くないと判断しました。技術書典はお祭りなので、出店から出店にすぐ移動できたほうが良い体験ではないでしょうか? そういった体験を考えた結果、一枚の交換券だけで欲しいものが手に入る方式にしてみました。こういった価格設定と先述した配布方法により、まあまあの体験を提供出来たかな、と思っています。
尚、公式から「後払い」アプリがリリースされていましたが、アプリ支払いと現金払いからみると、売上的には 2:8でした。後払いアプリもモダンではありますが、①スマホ取り出しからの④読み込み⑤それをサークルにみせて⑥サークルはそれを渡す、という手続きを踏まねばなりません。その点、現金は①千円を取り出す②渡す③サークルは本を渡す、とスピーディーです。したがって、しばらく現金前提で販売するのが良いな、と思いました(もちろん、後払いは引き続き利用)。
表紙担当としては、今回、正式にデザイナーさんに依頼をしました。まあ、現職の同僚なんですけど。サークルのコンセプトを伝えつつ、表紙のキャラをシャチにしたい、という良く分からない要望を、完全な形に落とし込んでくれました。ありがとうございます!お陰でサークル近くにおこしいただいた皆様が歩を止めて、興味を持ってくれるようになっていたと思います。
しかし、どちゃくそ格好よくないですか?シャチの可愛さとかっこよさが見事に共存していますね。青の濃淡をつかいわけることで、シャチが推進の浅いところへダイナミックに3D移動することを表現しているようです。他にも細かいセキュリティ関連のアイコンがキュートすぎます。凄い。すごすぎる。
最後に
もっと「このブースに寄ってよかったな〜」と思えるような体験を作ろうと思っています。具体的にはダウンロードカードをリッチにしたり、物理本を出すことです。先述の通りデザイナーさんに入ってもらうなど、一見して手にとりたくなるような体験を作って行くと同時に、セキュリティといえば「シャチ本」と誰もが思いつく世界にしていきたいと思います。
以上、今後とも宜しくお願いします。
P.S
- 販売数は336部。前回は90部くらいでした。
- シャチは私の趣味です。
- Boothでのダウンロード販売に向けて動いています。
DroidKaigi2018で発表した内容の補足とスタッフとしての役割
DroidKaigi2018でスピーカーとして「認証と認可と君と」というタイトルで話してきました。
また、併せて微力ながらもスタッフとしてお手伝いさせていただきました。
スピーカーとして
さて、技術的なところは今後ステップバイステップでコードともに説明していくと思うので、本稿ではエモいパート(序盤と終盤)のところのフォローをしようと思います。
序盤のエモい部分
序盤は何故、@ken5scalがこのテーマを攻めようと思ったかをFintechと業界絡めて話しています。 金融APIに求められるセキュリティ~APIDays Paris講演より|2017年2月号|金融ITフォーカス|刊行物|NRI Financial Solutions
上記の記事にある通り、Fintechという金融ビジネス上のイノベーションで、注力されようとしている分野は3つあると言われています。それが1) AI 2) Blockchain 3) オープンAPIです。その中でも特にオープンAPIに注目しています。企業単体ではできない・持てない価値を交換する窓口および経路として、シルクロードのような存在になると思っているからです。
そんなAPIを安全に守るため様々な対策が必要なのですが、そこで重要なのが認証と認可です。アクセス制御として第一の入り口となる認証・認可こそオープンAPI時代の要だと思い、今回のDroidKaigiのテーマとして取り上げさせて頂きました。
終盤のエモい部分
いくらOAuth2.0やFIDOを実装したところで、リスクから解放されることはありません。それぞれの仕様を安全たらしめているものがいつ危殆するかわからないからです。従って、目を光らせて最新の情報を追わなければなりませんが、既存の仕様を理解しつつ、常に最新を追うのは、これはなかなか骨です。そこで仲間が必要になるわけですが、なかなかセキュリティと開発が交わるチャンスは少ないです。願わくば、本セッションを通じて、すこしでも認証・認可について面白いと感じて頂いて、価値をユーザーに安全に提供するための仲間になっていただければ幸いです。
スタッフとして
相変わらず最高のチームでした。そんなチームですが、一端の中小企業の規模になりつつあり、参加者様も過去最多になりました。そのような状態で、どのように円滑・安全に運営していくかが、今後のワイの仕事になりそうです。 宜しくお願いします。
2017年を雑に振り返って、2018年の目標を雑に立てる
2017年振返り
1月
Android(Java)以外のプログラミングとして、初めてGoを弄り始める。自分ツールとして、GSuiteのコマンドラインツールをGoで作成。Slack Botも作成していたりしました。Reduxを勉強し始めている形跡があるが、正直ここらへんは自分のキャリアや人生に迷ってた間があります。後、副収入を得たのもここらへん。ちなみに、GSuiteツールキットは次のリポジトリ。正直ウンコだと思う。
2月
ちょびちょび前述のGSuiteのコマンドラインツールを作ってもいたけど、基本的にはDroidKaigiの準備をしていた模様。その過程で、使ってないActivityがあったら検知してくれるLintを作ったりしました。更新できてない... github.com
3月
DroidKaigiで「ドキッ★脆弱性 onCreate() から onDestroy() まで」発表。会社のアプリに脆弱性の報告をされたので、原因や対応フローといったのをコミュニティ内でシェア。Webアプリ(Railsエンジニア)の人と一緒にDockerデビュー。実はこのタイミングで、CISOの椅子を用意してくれていたスタートアップに転職しようとしていた。何やかんやあって、半年待ってもらうことに(結局、今の会社に残ったけど)
ドキッ★脆弱性 onCreate() から onDestroy() まで // Speaker Deck
4月
基本的に会社のことしかしてなかった。死ぬほど忙しかった。会社でWindowsサーバー・ドメコン・グループポリシーの権限部分でウンウン唸ってた。Twitterのタイムラインみると3am~4amまで仕事してた模様。引くわ〜。社長への報告とかもここから始まったかも。会社の全体的なセキュリティ方針とかお願いする予算とかも弾いてて、結構プレッシャー大きかった。ポッドキャスト「セキュリティのアレ」に準レギュみたいなポジションから参加したのも、ここらへんから。
5月
仕事については、大体4月と同じ。休日はTerraformをちょろっといじったりしてた。また、自分でコマンドラインを作ったりした結果、「もっとちゃんとプログラムの基礎やんないとなー」と思い立ってたのはここらへん。Googleが学生向けの技術開発者キャリアでやっておくべきことをリストしておいたので、そのチェックリストを作る。
6月
上記のを見て、暗号に関する授業をCourseraで修了。Andrew NG教授のMachine Learningもなんだかんだで終わってなかったの修了。両方ともCertificateは貰った。ただ、暗号の授業は面白かったけど、何となく思ってたのと違った。僕がのぞんでたのは、結城先生の「暗号技術入門」& 実装だったんだけど、Courseraは暗号が安全であるための数学的要件や攻撃方法がメインだった。なので「Javaで作って学ぶ暗号技術 - RSA,AES,SHAの基礎からSSLまで」を参考にして、Goを使った実装をしている。RSAとAESまでできたけど、SHAからSSLまでは出来てない。やるかは...わからない。色々やりたいことがあるので。あと、地味にGCP, コンテナ, k8sを使ったサイトを1つリリースしてた。更新は手動。
7月
仕事は相変わらず死んでたけど、技術的なことというより、非技術的な調整をしまくってて忙しかった。エンジニア is 何、セキュリティ is 何と超自問自答してた時期。
前述の暗号 in Goを実装しているときに、Techboosterのmhidakaさんにテクブで声をかけられる(もともとDroidKaigiで知り合いであった)。2つ返事でおkしたのが運の尽き。 ひーこらいいながら、AndroidのSMS Verifier APIについての初原稿を仕上げる。次のリンクから買えるで。
あわせて、ssmjpで話してほしいといわれたので、やはり何も考えずに受けて、ひーこらいってた。NISTからDigital Identity Guide (SP800-63)がでたので、そのSMS認証について話す。これを日本語で不特定多数の前で話したのは、僕が初めて...かも...?
俺のSMS認証がこんなに非推奨なわけがない // Speaker Deck
GoogleのSecurity Princessと呼ばれる方が書いたセキュリティを専門にするひとの心得、というのを日本語訳した。これが結構バズった。そしてビビった。
8月
仕事は相変わらず(略。で、プログラミングしなさすぎてヤバイな、と思ったので、隙間時間で会社で使ってるサービスのAPIを叩くクライアントアプリを作成。コマンドラインも作っておいた。ビルドは手動でmakeファイルさえ作ってない。地味にAWSを始める(インスタンス立てるだけじゃなく、組織の中でちゃんと使う)。SlackのChat Botもここら辺でデビュー
9月
ソフトウェア的な活動は特にせず。お仕事は一旦落ち着く。ちょっとダレる。夏休みとしてエストニアに旅行にいく。 e-govショールーム、Funderbeam、Transferwise、Verif、Cybernetica、SK IDソリューション、エストニア情報センター(RIA)に訪問したりしていた。終わった後に、自分が所謂「日本企業の視察・情報収集」しかしてないことに気づき、激しく自己嫌悪。いや、日本のFintech事情とか話したけど、貰った情報の価値からしたらちょっと...。尚、ご飯は口に合わなかった模様。歴史的にはものすごい面白く、なぜエストニアが現在のエストニアになったかが理解できた。そして、その歴史的背景無視して日本が真似してもしゃーないのでは、というスタンスになった。そんな間に会社が上場。
10月
GCP, k8sでのインフラ構築2サイト目を構築開始。技術書典3に「ニッチ・セキュリティ」サークルから「現時点で日本語でググっても出てきにくいセキュリティ技術」を出す。自分はUAF 1.1に書いたが、一緒に参加頂いたbbr_bbqさんと北原さんの記事のクオリティの高さに完全降伏した。幸い好評のうち終了。
11月
GCP, k8sでのインフラ構築2サイト目の構築終了。色々あって神経をすり減らす。
12月
上記のサイトでバックエンドサーバーが必要になったので、gRPCデビュー。サーバー側はGoで、クライアント側はRubyで書いた。再度、mhidakaさんに誘われて、テクブ本を書く。今回のテーマはFirebaseを使った認証。何だかんだ言ってKotlinまだ触ってなかったので、全てKotlinで書く。
ふりかえると
色々やってるな〜(小並 (´ε`;)ウーン…振り返ると殆ど仕事しかしてない気配です。何度か精神やばいな、っておもったことあるんで、ちゃんと休みはとろう。 今年の目標はQoLを上げるのも含めておいたいと思います。
で、これが去年の目標なわけだが、CISSP/機械学習/サービス作成というのができてませんな。 http://ken5scal.hatenablog.com/?page=1483260359
筋トレにあまりいけなくなっている事実は見過ごし難い。
そしてCNCFとの出会いや4月からの仕事で、完全に趣向が変わってきてはいる。
ブロックチェーンの流行りなど、新しい技術を眺めているだけでいいのだろうか。
CISSPとらなかったなあ
2018年の目標
やりたいことは沢山あるが、やはり基礎と認証・認可を固めて行こうと思う。また、攻撃技術は身に着けないとだめそう。コマンドライン自分で作ったけど、テストないと厳しい。QOLをあげるために、規則正しい生活を。
絶対やる
- アルゴリズムとデータ構造
- テスト
- 「テスト駆動開発」
- FIDO UAF1.1
- docomo Xperia XZ SO-01Jを買わないと...
- 一応PIXEL2も対応していそう Google Details the Pixel 2's Tamper-Resistant Hardware Security Module
- OAuth2.0/OIDC
- 「OAuth in Action」の写経
- RFCを片っ端から読む
- CTF
- ksnctf, マクニカctf
- Web Application Penetration Testing Training Course - WAPT - eLearnSecurity
- GWEB?
- CNCF
- 健康づくり
早く寝る。早く起きる。効率的にやるため、昼にyoutube、SNSをぐるぐるみるのやめる...やめたい...
朝ジム: いつものメニュー、有酸素運動、体幹作り
自分のスケジュールに依存しない形で、健康づくりしたい。
瞑想
* 野菜を食う。夜はなるべく食わない。
- 後、山登ります山
- GREを見据えた英語
- Discrete Mathematics, Computer Systems
時間があったら
- サービス作り。「Go Web Programming」
- CISSP, CISA?
- 「Real HTTP World」
- 機械学習 -> 原点に立ち返って考えると、わいは異常検知をやりたかっただけなんや...個人的に数冊本読んで、kaggleに手をだす?
- ブロックチェーン -> とりあえずフォロワーレベルでいいかな。本職はセキュリティで、いまだユースケースの確定してないところに本腰いれてつっこんでも迷子になるだけそう。入門書を数冊読んで、下を真似するぐらいで、今はいいかも。 Building Blockchain in Go. Part 1: Basic Prototype · Going the distance
Androidアドベンドカレンダー、Firebase Authenticationで電話認証する #Android #Authentication
Android アドベントカレンダー 20日目の記事です。
とある同人誌に掲載する予定だったのですが、風邪でぶっ倒れて書けなかった最終章をこちらに書きます。 内容は、Firebase Authenticationを使った電話認証のあれこれです。以降、「Firebase Authenticationの電話認証」を電話認証として略させて頂きます。 また、本稿ではFirebaseの仕組み上、みんなだいすき2要素認証ではなく2段階認証と呼称させていただきます。 詳しくはこちらをご覧ください。
本稿は次の内容でお送りします。 - ベーシックな電話認証 - 既存アカウントとのヒモ付け - 電話認証を使ったなんちゃって2段階認証 - SMS Retriever APIを使った半自動2段階認証
では、やってまいりましょう。
ベーシックな電話認証
いきなりで申し訳ないのですが、電話認証を実装したアプリはエミュレータ上では実行できません。いや、実行はできますが、電話認証周りの機能は動きません。クラッシュとかではなく単純に動きません。実機をご用意ください。
まずは電話番号をFirebaseに登録する必要があります。その場合、1) その電話番号が本当に実在するものか、2) 登録要求をリクエストしたユーザーのものであるか確認をとる必要があります。コードでお話すると、まず PhoneAuthProvider.getInstance().verifyPhoneNumber
で電話番号の存在を確認し、そして、その後SMS経由で送られた確認コードをユーザーから受理・検証することで、登録要求リクエストの真正性を確認します。
1) はFirebaseの PhoneAuthProcider.getInstance().verifyPhoneNumber
を使って出来ます。
// 該当の電話番号に確認コードを送った結果を受け取るコールバック mCallbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() { // 後でつかいます override fun onVerificationCompleted(p0: PhoneAuthCredential?) { Toast.makeText(this@EmailPasswordActivity, ": Verification Completed", Toast.LENGTH_SHORT).show() } // 後でつかいます override fun onVerificationFailed(p0: FirebaseException?) { Toast.makeText(this@EmailPasswordActivity, p0?.message, Toast.LENGTH_SHORT).show() } override fun onCodeSent(p0: String?, p1: PhoneAuthProvider.ForceResendingToken?) { mSMSVerificationID = p0.toString() } override fun onCodeAutoRetrievalTimeOut(p0: String?) { mSMSVerificationID = p0.toString() } } private fun registerPhoneNumber(phoneNumber: String) { PhoneAuthProvider.getInstance().verifyPhoneNumber( phoneNumber, // E.164フォーマットである必要があります。このフォーマットは[+][国コード][エリアコード]になります。例えば080-1234-5678が電話番号なら、E.164フォーマットで+818012345678です。 10, // 10秒でタイムアウトする TimeUnit.SECONDS, this@EmailPasswordActivity, mCallbacks ) }
2) は真正性確認になります。ユーザーが取得した確認コードとmCallback内で取得したSMS確認IDを組合せてたクレデンシャルがまずは作成されます。アプリはそれをサーバーに送信し、サーバーはそれを検証します。
val auth = FirebaseAuth.getInstance() val credential = PhoneAuthProvider.getCredential(mSMSVerificationID, verificationCode) auth.signInWithCredential(credential).addOnCompleteListener { task -> if (task.isSuccessful) { auth.currentUser?.let { updateResult(it) } } else { Log.w("Phone", "signInWithPhoneAuthCredential:failure", task.exception) Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show() } }
タスクが成功した場合、その時点で電話認証をしたユーザーはFirebaseに登録されていることになります。次の画像をご参照ください。
とてもハンディですね。
既存アカウントとのヒモ付け
でも、これでは既存アカウントに紐付いてません。単純に、新しい別のアカウントが生成されただけです。既存アカウントに紐付かせるために、電話認証で登録したアカウントを削除したうえで紐付かせたいアカウントにリンクさせてみましょう。下記の様にログイン済みのユーザーにクレデンシャル(SMS確認IDとSMSに送られた確認コード)をリンクさせればおkです実装すればおkです。
val auth = FirebaseAuth.getInstance() val smsCredential = PhoneAuthProvider.getCredential(mSMSVerificationID, findViewById<TextView>(R.id.mfa_code).text.toString()) auth.currentUser?.linkWithCredential(smsCredential)?.addOnCompleteListener { task -> // auth.currentUserはFirebase Authenticationですでにサインインしているホスト if (task.isSuccessful) { mAuth.currentUser?.let { updateResult(it) } } else { Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show() } }
ひも付きました。
次は2段階認証の話になります。
電話認証を使ったなんちゃって2段階認証
上記の通り、複数の認証プロバイダ(メールアドレス、電話番号)を1つのアカウントに紐付けることができました。そこでメアドとSMSを使った2段階認証を設定してみたいと思います。
注意: 今のFirebaseの仕組み上、メアド・パスワードの認証が成功した時点でサインインした状態になってしまいます。従って、一度サインアウトして更に電話認証する流れになります。なので、本章はなんちゃって
となっています。
流れとしては、signInWithEmailAndPasswordでサインインしたユーザーの情報から電話番号を取得し、確認コードを送ります。これはFirebaseのContinuationインターフェースを使って実現できます。ContinuationインターフェースではTaskの結果を受取り、任意の処理を実行・出力する実装ができます。
// 認証結果を元に、電話番号へ確認コードを送る class Send2FAVerificationCodeToSMS( private val executor: Executor, private val callback: PhoneAuthProvider.OnVerificationStateChangedCallbacks) : Continuation<AuthResult, Unit> { override fun then(task: Task<AuthResult>) { if (!task.isSuccessful || task.result.user.phoneNumber.isNullOrEmpty()) { return } return PhoneAuthProvider.getInstance().verifyPhoneNumber( task.result.user.phoneNumber.toString(), // Needs to be E.164 format. eg. +81805541xxxx(Japan), [+][country code][subscribed number with area code] 10, TimeUnit.SECONDS, executor, callback ) } } // 何となく別スレッドで処理したかった class ThreadPerTaskExecutor : Executor { override fun execute(r: Runnable) { Thread(r).start() } } // 上記をsignInWithEmailAndPasswordのタスク終了後に実行する mAuth.signInWithEmailAndPassword(email, password) .continueWith(Send2FAVerificationCodeToSMS(ThreadPerTaskExecutor(), mCallbacks)) .addOnCompleteListener { task -> signOut() //signInWithEmailAndPasswordが成功した時点で、サインイン済みになってしまっているのでサインアウトを実施 if (!task.isSuccessful) { Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show() return@addOnCompleteListener } else { Toast.makeText(this, "Verification Code has been sent", Toast.LENGTH_LONG).show() } }
手元の携帯電話に確認コードが送られてきました。前章で紹介したとおり、このコードと確認IDを組合せたクレデンシャルを引数にするsignInWithCredential
を呼び出せば、メールアドレス認証と電話認証を組合せた2段階認証の出来上がりです。
SMS Retriever APIを使った半自動2SV認証
ところで皆さん、2SVするとき電話番号入力するのめんどくさくありませんか?次のような手順を見て頂ければ、半分くらいのかたには同意頂けるかと思います。
- 自分の電話番号を入力
- サーバからの認証コードを待つ
- SMSまたは電話アプリを立ち上げる
- 認証コードを入力
このステップ2からステップ4までを自動化してくれる仕組み、それがGoogleがだしているSMS Retriever APIです。 当該APIを使うことで、サーバからSMSを受け取ったAndroid端末(のGoogle Play Service)がブロードキャストし、特定のアプリがそれを受信・SMSをパースできるようになります。 パースさえできれば、その後処理でサーバに認証コードを送るだけなので、ユーザー体験を損なわない自動的な2段階認証を提供できるわけです。
以下、実装を軽くみていきます。 注意: なお、筆者はスマホ(SIM Free機)と電話を分けて運用しているので、本章は動作確認できていません。
SMS Retriever APIの呼び出し
SmsRetrieverClient
インスタンスを生成し、startSmsRetriever()
を呼びます
立ち上がったAPIもといタスクは認証コードを含んだSMSが届くのを待ちます。5分立つとタイムアウトしますが、待ち時間は変更できます。
class PhoneNumberVerifier : Service() { private var smsRetrieverClient: SmsRetrieverClient? = null override fun onCreate() { smsRetrieverClient = SmsRetriever.getClient(this) } // このサービスは `PhoneAuthProvider.getInstance().verifyPhoneNumber` の実行直後に呼び出される override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) val action = intent.action if (ACTION_VERIFY == action) { val task = smsRetrieverClient!!.startSmsRetriever() task.addOnCompleteListener {task -> if (task.isSuccessful) { // 何か. smsRetriever開始成功のお知らせ } else { // 何か. smsRetriever開始失敗 } } }
SMSから認証コードの取り出し
認証コードが端末に届いた際、Google Playサービスが、SmsRetriever.SMS_RETRIEVED_ACTION
を指定した明示的なブロードキャストを発信します。このブロードキャスト内に認証メッセージが届くわけです。従って、アプリ内ではBroadcastReceiver
で本メッセージを抽出します。
class SmsBrReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { if (intent == null) { return } if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { val extras = intent.extras val status = extras!!.get(SmsRetriever.EXTRA_STATUS) as Status when (status.statusCode) { CommonStatusCodes.SUCCESS -> { val smsMessage = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String Log.d(TAG, "Retrieved sms code: " + smsMessage) } CommonStatusCodes.TIMEOUT -> doTimeout() else -> { } } } } }
ここで取得したsmsMessage = 確認コードを、前述のsignInWithCredentialにいれてFirebaseに送信することで、半自動2SVが完了します。
//mSMSVerificationIDはPhoneAuthProvider.OnVerificationStateChangedCallbacks()のonCodeSentから取得 val credential = PhoneAuthProvider.getCredential(mSMSVerificationID, code) mAuth.signInWithCredential(credential)
以上です。
終わりに
以上で、Firebase Authenticationの電話認証周りの紹介をさせていただきました。認証システムは設定するには非常に多くの考慮が必要ですので、Firebase Authenticationを利用すれば、ベストではないにせよ2段階認証までハンディに実装できるようになります。
High Sierraのパスワードレスrootログインの注意点と対策方法
話題になってるので、改めて説明をする必要はないと思うので、注意点・対策方法について記載しておく。
注意点
どこかの記事の対策として"root"を無効化する、とあった。でも、rootと打ち込むと勝手に有効化されるので意味がありません。パスワードを変更してから、無効化してください。
パスワード変更
ローカル管理者権限を持ってる場合
下記のうちいずれか
CLIベース
% sudo passwd root
GUIベース
システム環境設定 > ユーザーとグループ > ログインオプション > 編集
ディレクトリユーティリティを開く > 編集 > ルートパスワードを変更
↑のいずれの方法でも対策できるのは確認済み
組織内の端末管理者向け
組織の管理者だったら、Mac管理ツールで下記のスクリプトを配布すればいいと思います。こちらも大丈夫そう。検証してから使ってね。
Blocking logins to the root account on macOS High Sierra | Der Flounder
余談
報告者のtweetを見にいったところ、公開方式について ちゃんとDisclosure Policyに従って報告しろよ派
vs Appleが悪いのに何がダメなんだ。それを気にするのは報告者の責任ではない派
の論争が繰り広げられてて面白かった (コナミ。
GCPのIdentity-Aware Proxyためしてみた #GCP #IAP
GCPで動かしてるWebサービスのstg環境にIdentity-Aware Proxy(IAP)噛ませてみた。これにより外部からアクセスする際、ドメインのサイトにたどり着く前にGoogleアカウントの認証が必要になった。事前に許可されたGoogleアカウントでなければサイトにたどり着くことすらできなくなる。つまり、アカウントとクレデンシャルが正しかろうと、IAPに登録されてなければ、アクセス権限が一切ない状態になる。
設定方法は簡単で、「IAM & Admin」 > 「Identity-Aware Proxy」で対象のリソースでIAPを有効化させるだけ!簡単。
なお、Firewallでガバガバに設定していたりするとIAPをバイパス出来てしまう。その場合、warningサインがでていることになるらしい。僕の場合は、大体プロジェクト作成時にdefault firewall ruleを消してしまうので、そういうことはなかった。
* 元サイト
IAPをかませると誘導される画面
失敗画面(実在するアカウントでためした)
こいつのイカス所は、アクセス権限対象を細かく切れるところだと思う。 Googleアカウントはもちろんのこと、サービスアカウント、Googleグループメール、ドメイン全体など様々なスコープに対応している。例えば、外部協力会社さんが既に保持してるGoogleアカウントをそのまま使えることができる(GSuiteに新規登録して月額支払わなくていい)
以上。