web-dev-qa-db-ja.com

FIDO U2Fを使用して、ユーザーがWebサイトで認証できるようにするにはどうすればよいですか?

FIDO U2F仕様に関する最近のすべての話題で、私はテストベッドでテスト的にFIDO U2Fを実装し、最終仕様の今後のロールアウトに備えたいと思います。

これまでのところ、Yubicoが作成したFIDO U2Fセキュリティキーと、ChromeにインストールされているFIDO U2F(Universal 2nd Factor)拡張機能があります。また、Googleログインで機能するようにセキュリティキーを設定することもできました。

今、私は自分のサイトのためにこのようなものを利用する方法がわかりません。私はU2FプロジェクトについてGoogleのGithubページを調べ、その webアプリのフロントエンド を確認しました。とてもシンプルに見えます(JavaScriptのみ)。 FIDOで2番目の要素の認証を実装するのは、いくつかのJavaScript呼び出しを実装するのと同じくらい簡単ですか?例の登録で起こっていると思われるのはこれだけです:

      var registerRequest = {
            appId: enrollData.appId,
            challenge: enrollData.challenge,
            version: enrollData.version
      };

      u2f.register([registerRequest], [], function (result) {
          if (result.errorCode) {
        document.getElementById('status')
          .innerHTML = "Failed. Error code: " + result.errorCode;
        return;
          }
          document.location = "/enrollFinish"
          + "?browserData=" + result.clientData
          + "&enrollData=" + result.registrationData
          + "&challenge=" + enrollData.challenge
          + "&sessionId=" + enrollData.sessionId;             
      });

しかし、それを自分でどのように実装に使用できますか?このメソッド呼び出しからのコールバックをユーザー登録に使用できますか?

34
761838257287

あなたがやろうとしているのは、いわゆる「依存パーティ」の実装です。つまり、Webサービスは、FIDO U2Fトークンによって提供されるIDアサーションに依存します。

そのためには、 2F仕様 を理解する必要があります。特に、チャレンジ/レスポンスパラダイムの実装方法とアプリIDとファセットの動作方法。これについては、仕様で詳細に説明されています。

あなたの言うとおりです:アプリケーションのフロントエンドからFIDO U2Fを操作するために必要な実際のコードはほとんどありません(つまり、「低レベル」MessagePort APIではなく「高レベル」JavaScript APIを使用する場合) 。ただし、アプリケーションは、トークンによって生成されたメッセージを処理し、検証する必要があります。これは簡単なことではありません。

証明書利用者サイトの実装を追求する方法を説明するために、学術的な理由で最近プログラムした Virtual FIDO U2F Token Extension からいくつかのコード例を示します。完全なサンプルコードのページを見ることができます。


ユーザーがFIDO U2Fトークンを使用して認証する前に、ユーザーはregisterを使用して認証する必要があります。それらを許可するには、ブラウザでwindow.u2f.registerを呼び出す必要があります。そのためには、いくつかのパラメーターを指定する必要があります(繰り返しますが、詳細については仕様をお読みください)。その中で、アプリのchallengeidです。 Webアプリの場合、このidは、FIDO操作をトリガーするWebページのWeb Originでなければなりません。 example.orgであると仮定しましょう:

window.u2f.register([
    {
        version : "U2F_V2",
        challenge : "YXJlIHlvdSBib3JlZD8gOy0p",
        appId : "http://example.org",
        sessionId : "26"
    }
], [], function (data) {

});

ユーザーが「ユーザープレゼンステスト」を実行すると(たとえば、トークンに触れることで)、JSONオブジェクトである応答を受け取ります(詳細については、仕様を参照してください)

dictionary RegisterResponse {
    DOMString registrationData;
    DOMString clientData;
};

このデータには、アプリケーションでの作業が必要ないくつかの要素が含まれています。

Register Map of a FIDO U2F Registration Response Message

  1. 生成されたキーペアの公開キー-今後の認証で使用するために、これを保存する必要があります。
  2. 生成されたキーペアのキーハンドル-将来の使用のためにこれも保存する必要があります。
  3. 証明書-この証明書とCAを信頼するかどうかを確認する必要があります。
  4. 署名-署名が有効かどうか(つまり、証明書に保存されているキーを確認するかどうか)、および署名されたデータが期待されるデータかどうかを確認する必要があります。

最近、この情報を抽出および検証する方法を示すJavaの依存パーティサーバー用の 大まかな実装ドラフト を準備しました。


登録が完了し、生成されたキーの詳細を何らかの方法で保存したらsignリクエスト。

あなたが言ったように、これは、高レベルのJavaScript APIを介して、短く簡単に開始できます。

window.u2f.sign([{
    version : "U2F_V2",
    challenge : "c3RpbGwgYm9yZWQ/IQ",
    app_id : "http://example.org",
    sessionId : "42",
    keyHandle: "ZHVtbXlfa2V5X2hhbmRsZQ"
}], function (data) {

});

ここでは、登録中に取得したキーハンドルを指定する必要があります。もう一度、ユーザーが「ユーザープレゼンステスト」を実行した後(トークンに触れるなど)、JSONオブジェクトである応答を受け取ります(詳細については、仕様を参照してください)

dictionary SignResponse {
    DOMString keyHandle;
    DOMString signatureData;
    DOMString clientData;
};

ここに含まれる署名データを検証する必要があります。

Register Map of a FIDO U2F Authentication Response Message

  1. 署名が以前に取得した公開キーと一致することを確認する必要があります。
  2. また、署名された文字列が適切であることを検証する必要があります。

これらの検証を実行すると、ユーザーが認証されたと見なすことができます。そのためのサーバー側コードの簡単な実装例は、my server example にも含まれています。

49
mritz_p

私は最近、この手順と すべてのU2Fサーバーライブラリをリストする (ほとんどが完全に機能するデモサーバーをバンドルしている)、開発者.yubico.com/U2F。目標は、開発者が仕様を読むことなくU2Fを実装/統合できるようにすることです。

免責事項:私はYubicoで開発者として働いています。

22
minisu