以前の投稿 「FIDOデバイスエミュレータを作成してみた(これが最後)」 で、FIDO2のデバイスエミュレータの作成を試みて、断念していたのですが、久しぶりに挑戦して、原因がわかり、完成できました。
ソースコードもろもろを以下のGitHubに上げてあります。
poruruba/fido2_server
ただ、いくつかのサイトで動かしていますが、動かないサイトがあります。おそらく、FIDOアライアンスのCertifiedデバイスではないからかと思います。たとえば、AWSのWebコンソールへのログインのためのFIDOデバイスとして登録できますが、認証時に失敗しています。。。
目指す構成
本来、FIDO2デバイスは以下の構成で使います。ブラウザとFIDO2デバイスの間は、BLEかNFCかHIDで通信します(ブラウザの実装状況にも寄りますが)。
FIDO2対応サーバ
⇔(HTTPS)
ブラウザ
⇔(BLE、NFC、HID)
FIDO2デバイス
目指す構成は以下の構成です。
FIDO2対応サーバ
⇔(HTTPS)
ブラウザ
⇔(BLE)
M5StickC
⇔(HTTP)
FIDOデバイスエミュレータ
FIDO2デバイスの代わりにM5StickCを使い、BLEでブラウザと通信します。
ちなみに、M5StickCは単に背後にあるWebサーバ(FIDOデバイスエミュレータ)に転送しているだけです。
今回、羽陽曲折しましたが、FIDOデバイスエミュレータをNode.jsで作成することができました。
今回直したところ
以下に仕様定義されていたのですが、実装が漏れておりました。というか気づきませんでした。
・0x07 ("check-only"): if the control byte is set to 0x07 by the FIDO Client, the U2F token is supposed to simply check whether the provided key handle was originally created by this token, and whether it was created for the provided application parameter. If so, the U2F token must respond with an authentication response
message:error:test-of-user-presence-required (note that despite the name this signals a success condition).
やられた。。。。
0x07のときには、「message:error:test-of-user-presence-required」を返すべきとのこと。
そして、それがこれのこと。
SW_CONDITIONS_NOT_SATISFIED (0x6985): The request was rejected due to test-of-user-presence being required.
これを直したらあっさり動きました。。。
追加で直したところ
x509v3証明書を作成するために、npmモジュールであるjsrsasignを使っていたのですが、脆弱性があったらしく、最新にアップデートすると、インタフェースが変わっているため、変更が必要でした。
以前の書き方。
var tbsc = new rs.KJUR.asn1.x509.TBSCertificate();
tbsc.setSerialNumberByParam({'int': 1234});
tbsc.setSignatureAlgByParam({'name': 'SHA256withECDSA'});
tbsc.setIssuerByParam({'str': "/CN=FT FIDO 0200"});
tbsc.setNotBeforeByParam({'str': "190511235959Z"});
tbsc.setNotAfterByParam({'str': "340511235959Z"});
tbsc.setSubjectByParam({'str': "/CN=FT FIDO P2000000000000"});
tbsc.setSubjectPublicKey(kp.pubKeyObj);
var cert = new rs.KJUR.asn1.x509.Certificate({'tbscertobj': tbsc, 'prvkeyobj': kp_cert.prvKeyObj });
cert.sign();
新しい書き方
var cert = new rs.KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: serial_no++ },
issuer: { str: "/CN=" + FIDO_ISSUER},
notbefore: FIDO_EXPIRE_START,
notafter: toUTCString(new Date(Date.now() + FIDO_EXPIRE * 24 * 60 * 60 * 1000)),
subject: { str: "/CN=" + FIDO_SUBJECT },
sbjpubkey: kp.pubKeyObj, // can specify public key object or PEM string
sigalg: "SHA256withECDSA",
cakey: kp_cert
});
その他直したところ
M5StickC
・LCDに通信状態を表示するようにしました。
・M5StickCにおいて、BLEコネクション切断されたときには、3秒ほど、BLEアドバタイズを停止させ再度起動するようにしました。(そうしないと、ブラウザが見つけてくれなかった)
FIDO2エミュレータ
・生成した認証情報をファイルに保存するようにしました。
・x509v3証明書の署名鍵を共通にして、ファイルに保存しておくようにしました。
FIDO対応サーバ
・ユーザ情報をファイルに保存するようにしました。
認証や登録を繰り返していると、 data/fido2_device/ や、data/fido2_server/にたくさんファイルができてくるので、不要なファイルは削除してあげてください。
立ち上げ方法
以下から、まるごとZIPダウンロードします。
https://github.com/poruruba/fido2_server
■FIDO2エミュレータ兼FIDO対応サーバ
フォルダfido2_serverにあります。
> unzip fido2_server-master.zip
> cd fido2_server-master
> cd fido2_server
> mkdir data
> mkdir data/fido2_device
> midir data/fido2_server
> mkdir cert
> touch .env
> node app.js
HTTPSが必要であるため、SSL証明書が必要です。certフォルダに置きます。
.envには以下を記載します。ポート番号です。
SPORT=443
PORT=10080
いくつか環境に合わせて書き換えるところがあります。その他、以前の投稿を参考にしてください。
WebAuthnを使ったFIDOサーバを立ててみた
ちなみに、当時はfido2-libの修正が必要な個所が何件かありましたが、そのうちの1件は最新では修正されているようでした。
■M5StickC
フォルダFido2Gatewayにあります。
いくつか環境に合わせて書き換えるところがあります。その他、以前の投稿を参考にしてください。
FIDOデバイスエミュレータを作成してみた(だけどもうちょっと。)
使ってみる
まずは、今回同時に立ち上げた、FIDO対応サーバで動作確認。
https://【立ち上げたサーバのホスト名】/fido2/index.html
詳細は以下をご確認ください。
WebAuthnを使ったFIDOサーバを立ててみた
ちなみに、今回の画面キャプチャでは、Windows PCでの画面ですが、Androidでも同様に動作を確認できます。(以前投稿したときと表示が変わっているようで、以前のほうがかっこよかったです。。。)
それから、BLEで通信するには、最初に、WindowsのBLE設定で、M5StickCとペアリング設定しておく必要があるようです。
登録開始ボタンを押下。
登録実行ボタンを押下。
これで、FIDO2デバイスの登録が完了しました。
続けて、認証してみましょう。ログイン開始ボタンを押下。
ログイン実行ボタンを押下。
認証成功です。
試しに、他のサイトでも確認してみます。
Registerボタンを押下
今度は、Authenticateボタンを押下
以下のサイトも。
登録ボタンを押下
次は認証。ログインボタンを押下。
以上
↧