WebAuthn と macOS Touch ID

WebAuthn API で macOS の Touch ID が Chrome M70 で使えるようになった、というのを Chrome リリースノートを見て気になっていたので試した。

FIDO2 も触ろうと思ったが対応デバイスを持っていなかったので macOS Touch ID でごまかした。

結果

Image for post
Image for post
shiguredo.jp で WebAuthn
Image for post
Image for post
shiguredo.jp で WebAuthn で Touch ID

ブラウザ側の実装は簡単だった。JavaScript をチョロチョロっと書くだけ。それ以上は特にない。

この辺を参考にしながら実装すれば良い。

WebAuthn

WebAuthn というのはそもそもなんだというのを自分の理解で書いていく。ハードウェアトークンを利用し、公開鍵と秘密鍵を利用した使った認証の仕組みと理解した。

理解した部分を簡単に書いていく。細かいのは省略する。

デバイス登録

サーバからチャレンジ(32 バイトの暗号的に問題のない乱数)をブラウザがサーバから取得する。その際 RP (Relying Party) としてそのサイトのドメインと名前 (Id) を取得する。

さらに、ユーザ情報として、 ユーザ ID (バイナリ) 、ユーザ名、ユーザ表示名も送られてくるはず。ちなみにアイコンの URL も指定できる。

あとはローカル認証で Touch ID を実行すれば秘密鍵と公開鍵が生成され、さらに RP に秘密鍵で署名するという一連の流れになる。

あとはそれらの情報をブラウザがサーバに送ってしまえばいい。サーバは署名を公開鍵で確認して問題がなければユーザ情報と公開鍵をセットにデータベースに保存しておく。

これで認証デバイスとユーザが紐付いた。

デバイス認証

デバイス登録と流れは一緒でサーバからチャレンジやユーザ情報をもらう。ここで違うのはすでに登録されているドメインであれば、鍵を利用して署名するだけで良くなる。あとはそれらの情報をサーバに送ってサーバ側は保存されている公開鍵を利用して署名をチェックするという流れ。

つまり普通の公開鍵の仕組みをうまくブラウザから利用できるようになっているというところが最大の魅力。

今回は Touch ID (プラットフォーム)を試したが FIDO2 (クロスプラットフォーム)にも対応しているので、Yubikey 5 などを利用すればハードウェアーキーを利用することもできる。 Touch ID と USB デバイスの両方を登録しておくという事も可能だ。

ちなみにこの USB とやり取りするプロトコルを CTAP (Client to Authentication Protocol) というらしい。USB や Touch ID のような生体認証以外に NFC や BLE などとやりとりができる。

FIDO2

WebAuthn を利用するだけなら FIDO2 を理解しなくて良いことがわかったので調べない。YubiKey 5 が来たら動かしてみる程度にする。

よくわかってないこと

Yubikey のような場合、鍵のペアをどのくらい保存できるものなのだろうか?鍵のペアをドメインごとに生成するという認識なので 1000 サイトとかだったら 1000 個鍵のペアを持ってくれるのだろうか?

また Touch ID で生成された鍵のペアはどこでみれるのだろうか? 消せたりするのだろうか?

Twitter で教えていただいた。

YubiKey に登録されているのはハードコードされた秘密鍵であり、それを利用して RP ごとに公開鍵を生成?してるようだ。

ちょっと秘密鍵から複数の公開鍵が生成できるのかどうかは正直わからなかった。公開鍵なんだから全部同じ公開鍵でいい気がする。もしかすると毎回同じ公開鍵を生成してるじゃないだろうか。ここはもう少し調べたほうがいい気がした。

とりあえず YubiKey 側には保存しないというのがわかったのは大きい。インターネッツ本当にありがたい。

インターネッツ凄いし本当にありがたい。ということで素敵な記事を教えていただいた。

YubiKey の U2F の実装は秘密鍵を HMAC-SHA256 で生成していると。それに使うのが RP Id と Nonce と YubiKey 固有のシークレットキーということだった。

で、秘密鍵から公開鍵を生成して、サーバには其の公開鍵と Nonce をセットにして送る。認証時にはサーバから Nonce も送られてくるのでその Nonce と RP Id と YubiKey 固有のシークレットキーで秘密鍵を動的に生成して署名すればよい。

これで秘密鍵をハードウェア側に保存しておく必要がなくなる。

納得した。本当に皆様ありがとうございます。

なぜ WebAuthn なのか

パスワードうつのだるいし、1Password 愛用してるけどそれでもめんどくさい。ウェブの認証をスマホの生体認証に飛ばしてくれたりしたら本当に最高だと思う。

また社員の持ち出さない PC には Yubikey 5 をくっつけたりすることでいろいろうまくやってみたい。

ハードウェアートークンの歴史はそもそも凄い古いし、新しい技術ということではないと思っていて、むしろそれが Web というプラットフォームで使えるようになったというのは本当に素晴らしいと思っており、これは触っておきたいという思いから。

あと仕事で使えたら面白そうだなとも思っている。理解あるお客様は受け入れてくれそうなので。

今後

FIDO2 な Yubikey 5 で動いたら終わりにする予定。あとは仕事で使えたら使う程度で。どんな仕組みで実現しているのかをなんとなく理解しているで十分。

Written by

Erlang/OTP / 時雨堂 / WebRTC / E2EE

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store