FIDOとWebAuthnとCTAPのはなし
Monaca UG TOKYO #9
2019.6.12
Satoshi Suzuki
@gebo
自己紹介
• 鈴木 智(Satoshi Suzuki)
• 株式会社イードクトル
• Windows/ICカード/NFC/BLE/認証系
• いわゆるWebエンジニアではありません(汗
• Twitter @gebogebogeboge
• GitHub @gebogebogebo
• Qiita @gebo
– Follow Me
今日の話 ~利用者認証の話~
• パスワードについて
• FIDO パスワードを使わない認証
• WebAuthn JavaScriptについて
• CTAP プロトコルについて
パスワード=最近はやたらめんどくさい
• 強度が足りませんとかいわれたり
• 使いまわしてはいけないとかいわれたり
• サービスの都合で突然変更を要求されたり
• 漏洩したかもしれんから、このサイトからチェックするように
とかいわれたり
• ソーシャルログイン、どれで入ったっけ・・・
• その場の思い付きでパスワード登録して二度と
ログインできない・・・
そんな パスワード いくつ持っていますか?
パスワードの数
時代
大昔 昔
~ suzukiの場合 ~
大昔(パスワード10個以下)
- 誕生日とか憶えやすいもの
- 手帳に書いて持ち歩く
昔(20個くらい)
- すべて同じパスワードにしてみる
前(30個くらい)
- スマホのアドレス帳に保存
最近(100個以上)
- スマホのアプリ
- Chromeのパスワードマネージャ
パスワード どうやって管理してますか?
前 最近
スマホのアプリ、パスワードマネージャ
• パスワードの自動生成、自動入力
– 勝手に入力されるので、まったく記憶してない
– スマホを失くしたら大変なことに・・・
• クラウド管理でデバイス間自動連携
– 便利だし、無料だが
– どこにどうやって保管されているんだ?
– ヨソの国のハッカーに取られたりしない?
– 漏洩したときの保証は?
漏洩漏洩漏洩漏洩漏洩
GIZMODO 2019.05.24
https://www.gizmodo.jp/2019/05/google-failed-to-fully-secure-g-suite-passwords-for-
14-years.html
日経コンピュータ 2019.03.01
https://tech.nikkeibp.co.jp/atcl/nxt/mag/nc/18/020600011/022600026/
パスワードはもう限界・・・
そこで FIDO Alliance
ふぁいどあらいあんす、Fast IDentity Online Alliance
生体認証などを利用した新しいオンライン認証技術の標準化を目指して
2012年7月に発足した非営利の標準化団体、業界団体
世界のパスワード問題を解決する
https://fidoalliance.org/
FIDO全体像
https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API
FIDO全体のうち 今日はフロントエンドだけ
このへん
https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API
• 世界のパスワードの問題を解決するJavaScript
• FIDO AllianceとW3Cが策定
• 2019/3/4 W3C勧告
• Edge/Chrome/FireFoxが実装済み(Safariは間もなく?)
• Windows/Mac/Android対応(iOSは微妙)
というわけで WebAuthn
うぇぶ・おーすん / Web Authentication API
• Webで公開されているデモサイトの操作デモ
– https://webauthn.io/
• ブラウザ(Edge)でログインするデモ
• それぞれ 登録 → ログイン の操作
• デモ① セキュリティキー×PIN
– Security Key by Yubico
• デモ② セキュリティキー×指紋
– BioPassFIDO2 FEITIAN
まずは デモ
BioPassFIDO2
FEITIAN
DEMO MOVIE
https://www.youtube.com/watch?v=wA0tYNf2mbo
WebAuthn ってどんなAPI?
• navigator.credentials.create()
– セキュリティキーの登録、認証情報を取得する
– 引数=publicKeyルートのJSONを指定する
– 戻り値= Attestationオブジェクト、中に色々入っている
• navigator.credentials.get()
– セキュリティキーでユーザー認証する
– 引数=publicKeyルートのJSONを指定する
– 戻り値= Assertionオブジェクト、中に色々入っている
navigator.
credentials.
create()
navigator.
credentials.
get()
navigator.
credentials.
create()
var options = {
rp: {
id: location.host,
name: location.host,
},
user: {
id: new Uint8Array([129, 230, 232]),
name: "gebo",
displayName: "gebo",
},
challenge: window.crypto.getRandomValues(new Uint8Array(32)),
pubKeyCredParams: [
{
type: "public-key",
alg: -7, // cose_alg_ECDSA_w_SHA256,
},
],
}
// 認証にパスするとthenに入る
navigator.credentials.create({ "publicKey": options })
.then(function (attestation) {
// Success→attestationをVerifyし、中からCredentialID、公開鍵を取り出す
}).catch(function (err) {
// Error
});
Qiita:青いYubiKeyをFIDO2.0で光らせたい
https://qiita.com/gebo/items/33c48de1027f53f2712a
navigator.
credentials.
create()
メンバ 説明
rp.id RPID(Relying Party)
サービス提供者ID、登録時のキー
rp.name Relying Partyの名前
user.id 登録するユーザーのID、登録時のキー
user.name ユーザーの名前
user. displayName ユーザーの名前(表示用)
challenge チャレンジ - 乱数
登録後に返ってくるattestationの中に
チャレンジに対する署名が入る。
署名を検証してattestationの有効性を確
認する。
pubKeyCredParams.type public-key 固定
pubKeyCredParams.alg attestationに入る公開鍵の暗号化アルゴ
リズムを指定する。IANA-COSE-ALGS-REG
で定義されている値。
このサンプルでは -7 なので ES256 という
意味
- オプションは全てではありません。一部省略されています
- サンプルソースの値は かなりいいかげん です
- でも、動くことは動く
- attestationの検証は↓サイト
Qiita:青いYubiKeyをFIDO2.0で光らせたい
https://qiita.com/gebo/items/33c48de1027f53f2712a
navigator.
credentials.
get()
let credentialId = create()で取得したものをセット;
var options = {
challenge: window.crypto.getRandomValues(new Uint8Array(32)),
allowCredentials: [
{
type: "public-key",
id: Base64toUint8Array(credentialId),
}
],
}
// 認証にパスするとthenに入る
navigator.credentials.get({ "publicKey": options })
.then(function (assertion) {
// Success
}).catch(function (err) {
// Error
});
Qiita:青いYubiKeyをFIDO2.0で光らせたい
https://qiita.com/gebo/items/33c48de1027f53f2712a
navigator.
credentials.
get()
メンバ 説明
challenge チャレンジ - 乱数
登録後に返ってくるassertionの中にチャ
レンジに対する署名が入る。
署名を検証してassertionの有効性を確認
する。
allowCredentials.type public-key 固定
allowCredentials.id create()のときに取得したCredentialIDを
Base64で指定する。
Qiita:青いYubiKeyをFIDO2.0で光らせたい
https://qiita.com/gebo/items/33c48de1027f53f2712a
これがパスワードの問題を解決するの?
従来の認証モデル
ID GEBO
パスワード GeboGebo123
認証サーバー
DB
ID:GEBO
パスワード GeboGebo123
• サーバーでパスワードを保管 – 対称鍵
• IDとパスワードの1要素認証
従来の認証モデル
ID GEBO
パスワード GeboGebo123
認証サーバー
DB
ID:GEBO
パスワード GeboGebo123
• サーバーでパスワードを保管 – 対称鍵
• IDとパスワードの1要素認証
FIDOの認証モデル
• 公開鍵基盤(PKI)- 非対称鍵
– サーバーにパスワードを持たない
ID:GEBO
公開鍵
DB
認証サーバー
電子署名
Attestation/Assertion
チャレンジ
セキュリティキー
(Authenticator)
・秘密鍵
・PIN/生体
FIDOの認証モデル
• セキュリティキーとPIN/生体による2要素認証
ID:GEBO
公開鍵
DB
認証サーバー
電子署名
Attestation/Assertion
チャレンジ
セキュリティキー
(Authenticator)
・秘密鍵
・PIN/生体
FIDOの認証モデル
• 登録サービス毎に異なる秘密鍵/公開鍵を生成する
• PIN/生体は一つ→サービス毎に憶える(用意する)必要はない
ID:GEBO
公開鍵ADB
サービスA
セキュリティキー
(Authenticator)
・PIN/生体
ID:GEBO
公開鍵BDB
サービスB
秘密鍵A
秘密鍵B
FIDOモデルの安全性
• 公開鍵が漏洩したら?
– 公開鍵でログインすることはできないので問題ない
• 電子署名が漏洩したら?
– 毎回異なるチャレンジに対する署名なので問題ない
• 秘密鍵の管理は?
– 登録のたびに異なる秘密鍵を生成
– 秘密鍵はセキュリティキーの安全な領域で管理され、取り出すことができない
– 秘密鍵へのアクセスはPINまたは生体によって可能であり、署名作成の計算機能を利用するだけ
(アクセス=鍵を取り出すのではない)
– 一定回数のPIN誤りでロックされる
– これらの機能の実装を保証するFIDO Alliance認定ロゴ
ところで CTAP
しーたっぷ / Client-To-Authenticator Protocol
• セキュリティキーとの通信プロトコル
• 仕様はFIDOAllianceが策定/公開
– Proposed Standard, January 30, 2019
– https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-
authenticator-protocol-v2.0-ps-20190130.html
• HID/NFC/BLE
BioPassFIDO2
FEITIAN
MultiPass FIDO® Security Key
FEITIAN
• ブラウザがCTAPを実装し、WebAuthnAPIにしている
• なので、Webエンジニアの方々はWebAuthnを知っとけば、CTAP
のことは知らなくてもヨシ!
CTAP
USB
NFC
BLE
WebAuthn
UserApp
CTAPのことは知らなくてもヨシ、なんだけど
• 仕様が公開されているということは、誰が知ってもヨシ、ということ
• CTAPを実装すれば、WebAuthn無しでもFIDOセキュリティキーが使
える
C#で作ってみた
FIDOキーを使った試み on @Qiita
• WebAuthnぽいことができるWinデスクトップアプリ用ライブラリ
– WebAuthnModokiDesktopβ
– https://qiita.com/gebo/items/f6d3024f7e164ac0a195
• FIDO2セキュリティキーで電子署名をする試み
– https://qiita.com/gebo/items/0a08bc0e1aea6bc12c96
• FIDO2セキュリティキーでリモートデスクトップをする試み
– https://qiita.com/gebo/items/01b14279849c5fd399f7
まとめ
• WebAuthnを使うとユーザーはパスワード憶えなくていいし、事業者は漏洩などの
心配事が減るのでみんな幸せになる(これで漏洩の可能性がゼロになるわけではない)
• けど、FIDOの仕様を理解してフロントエンド、バックエンドの実装が必要
• また、Attestation/Assertionの署名はちゃんとVerify(検証)しないと、いつか誰か
に怒られます
• ので、自前での実装はかなり大変(雰囲気では無理)
• FIDOを実装したサービス、ライブラリがたくさん出てきているので自前で実装する
のではなく、それらを活用するほうがよい
• WebAuthn Awesomeというサイトにリンク集があるのでお勧め
– https://github.com/herrjemand/awesome-webauthn/blob/master/README.md
ありがとうございました

FIDOとWebAuthnとCTAPのはなし