2017年11月29日

YubikeyのU2F認証の仕組み(登録件数が無限なしくみ)

Yubikeyは、セキュアエレメント搭載のセキュリティーキーですが、
そういえばFIDOのU2Fには何件対応しているのだろう、と思いました。

FIDOのU2Fは、認証デバイスが鍵ペアを生成して保管し、
それを認証デバイス側と、サイト側で相互に突き合わせて強固な認証を行います。

Yubikey内のストレージは有限かつ少量で、それは各機能の登録データ数の制限等を見ると明らかです。
しかしながら、U2F認証を要求するサイトは数十、数百と増えるでしょう。
そうした時に、上限に達したらどうなるのか?

これ以上登録できませんとなるのか?削除の仕組みがある?それともまさか古い順に削除される?
調べてみると、公式サイトに回答がありました。

how many services can the u2f-certified YubiKeys be associated with?
https://www.yubico.com/support/knowledge-base/categories/articles/many-services-can-u2f-certified-yubikeys-associated/

「利用できるサービスの数の制限はありません。
 鍵ペアは生成されますが、デバイスには保存されず、登録サービスに保存されます。
 そのため実質的に無限に登録できます。」

最初これを見たとき、「え?」となりました。
・鍵ペアをサービスに保存したら意味なくない?
・Yubikeyからどうやって認証してるんだ?
・そもそもFIDOの仕様に、サイト側に保存する仕組みなんてあったっけ?

開発者向けサイトに答えがありました。
なかなかおもしろい仕組みを使って実装されています。

Key generation - Yubico Developers
https://developers.yubico.com/U2F/Protocol_details/Key_generation.html

ただしこれも理解に時間がかかったので、自分の理解の結果を以下に示します。
誤りが含まれているかもしれません。上記のURLの内容そのままといえばそのままですので、ご確認ください。

前提
・キーデバイスは、AppID(ドメイン名含む)でサイトを識別する。(これがフィッシング対策になる)
・同じサイトで、違うアカウントの認証情報が必要な場合があり、AppIDでは識別できない。
 そのために鍵の識別はKeyHandleを用いて行う。このKeyHandleは、デバイスが生成してサイトに送る。
・しかし、そうしたところで、セキュアなストレージが大量に必要になる。
 FIDOは鍵の格納方法を指定していないため、Yubikeyでは違ったアプローチをしている。

登録フェーズ
1. Webサービスは、AppID、Challenge(リプレイ攻撃対策乱数)とともに登録リクエストをする
2. Yubikey内で、乱数からNonceを生成する。
3. Yubikey内で、AppIDとNonceをデバイス内部鍵(固定)で署名ハッシュを取り、
 これを秘密鍵とする。
4. Yubikey内で、秘密鍵から公開鍵を生成する。
5. Yubikey内で、AppIDと秘密鍵、デバイス内部鍵(固定)で署名ハッシュを取り、
 秘密鍵ハッシュ(MAC)を生成する。
6. Yubikey内で、NonceとMACの一部を結合し、KeyHandleとする。
7. Yubikey内で、公開鍵・KeyHandle・Challenge・AppIDを秘密鍵で署名し、サービスに返す。
8. 内部カウンタを加算する。

認証フェーズ
1. Webサービスは、AppIDとKeyHandle、Challenge(リプレイ攻撃対策乱数)を渡して認証要求する
2. Yubikey内で、KeyHandleから登録時のNonceと秘密鍵MACを取り出す
3. Yubikey内で、AppIDとNonceをデバイス内部鍵(固定)で署名ハッシュを取り、これを秘密鍵とする。
4. Yubikey内で、秘密鍵から公開鍵を生成する。
5. Yubikey内で、AppIDと秘密鍵、デバイス内部鍵(固定)で署名ハッシュを取り、
 秘密鍵MACを生成する。これを、KeyHandleから取り出したMACと比較し、正しいか検証する。
 (正しくなければ、これはこのYubikeyのものではないか、あるいは改変されている)
6. Yubikey内で、KeyHandle・Challenge・AppIDを署名し、サービスに返す。
7. 内部カウンタを加算する。

結論として、Yubikey内には、秘密鍵も公開鍵もKeyHandleも保存されない。
デバイス内部鍵は、Yubikeyに出荷時に書き込まれているものであり、取り出しも変更もできない。
内部的に変化するのはカウンタだけである。

秘密鍵は、NonceとAppIDと、デバイス内鍵の3つから「毎回」生成されている。
Nonceは、登録時は乱数だが、認証時は登録時に渡したKeyHandleがサービスから帰ってくる。
KeyHandleは、Nonceと秘密鍵MACを結合したものであり、そのためこれで秘密鍵生成データが揃うことになる。

このままだと、全く登録していないサービスなどから要求されても、
無効な署名を渡してしまうが、それはKeyHandleに含まれている秘密鍵MACを使うことで
KeyHandleが自分が生成したものかをチェックできる仕組みになっている。

よくできている。
posted by gpsnmeajp at 14:08| Comment(0) | TrackBack(0) | 日記
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/181706880
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック