【问题标题】:How do I use FIDO U2F to allow users to authenticate with my website?如何使用 FIDO U2F 允许用户通过我的网站进行身份验证?
【发布时间】:2014-10-29 18:07:37
【问题描述】:

鉴于最近围绕 FIDO U2F 规范的所有热议,我想在测试平台上以测试方式实施 FIDO U2F,为即将推出的最终规范做好准备。

到目前为止,我有一个 Yubico 生产的 FIDO U2F 安全密钥和安装在 Chrome 中的 FIDO U2F(通用第二因素)扩展程序。我还设法设置了安全密钥以使用我的 Google 登录。

现在,我不确定如何将这些东西用于我自己的网站。我浏览了 Google 的 Github 页面以了解 U2F 项目,并查看了他们的 web app front-end。它看起来非常简单(仅限 JavaScript)。 那么使用 FIDO 实现第二因素身份验证就像实现几个 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;             
      });

但是我如何自己使用它来实现呢?我可以使用此方法调用的回调进行用户注册吗?

【问题讨论】:

    标签: google-chrome authentication fido-u2f


    【解决方案1】:

    您要做的是实现所谓的“依赖方”,这意味着您的 Web 服务将依赖 FIDO U2F 令牌提供的身份断言。

    您需要了解U2F specifications 才能做到这一点。尤其是挑战-响应范式是如何实现的,以及应用程序 ID 和方面如何工作。这在规范中有详细描述。

    您是对的:从应用程序的前端使用 FIDO U2F 所需的实际代码几乎是微不足道的(也就是说,如果您使用“高级”JavaScript API 而不是“低级”消息端口 API)。但是,您的应用程序将需要使用令牌生成的消息并对其进行验证。这不是小事。

    为了说明如何实现依赖方站点,我将给出一些代码示例,这些示例取自我最近出于学术原因编写的Virtual FIDO U2F Token Extension。您可以查看完整示例代码的页面。


    在您的用户可以使用他们的 FIDO U2F 令牌进行身份验证之前,他们需要向您注册它。 为了允许他们这样做,您需要在他们的浏览器中调用window.u2f.register。为此,您需要提供一些参数(同样;请阅读规范了解详细信息)。 其中有一个challenge 和你应用的id。对于 Web 应用,此 id 必须是触发 FIDO 操作的网页的 Web 源。假设它是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;
    };
    

    此数据包含您的应用程序需要使用的几个元素。

    1. 生成的密钥对的公钥 -- 您需要存储它以备将来验证使用。
    2. 生成的密钥对的密钥句柄 -- 您还需要存储它以备将来使用。
    3. 证书 -- 您需要检查您是否信任此证书和 CA。
    4. 签名 -- 您需要检查签名是否有效(即确认与证书一起存储的密钥)以及签名的数据是否是预期的数据。

    我已经为 Java 中的依赖方服务器准备了一个 rough implementation draft,它展示了最近如何提取和验证这些信息。


    一旦注册完成并且您以某种方式存储了生成密钥的详细信息,您就可以签署请求。

    正如您所说,这可以通过高级 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;
    };
    

    您需要验证此处包含的签名数据。

    1. 您需要确保签名与您之前获得的公钥匹配。
    2. 您还需要验证签名的字符串是否合适。

    执行这些验证后,您可以认为用户已通过身份验证。我的server example 中也包含了服务器端代码的简短示例实现。

    【讨论】:

    • 注意Chrome要求appId为https,如果使用http会返回错误码。在 github.com/google/… 的 Chrome 参考代码中描述了一些解决方法
    【解决方案2】:

    我最近在 developers.yubico.com/U2F 上写了这方面的说明,以及listing all U2F server libraries(其中大多数捆绑了一个完全工作的演示服务器)。目标是让开发人员无需阅读规范即可实现/集成 U2F。

    免责声明:我在 Yubico 担任开发人员。

    【讨论】:

    • 您知道是否存在任何客户端库吗?以创建 Yubico Fido 模拟器为例。
    • @Muis 在 FIDO 术语中,client 是与 U2F 设备对话的软件。如果这就是您想要的,可以使用a couple of libs。如果您要查找的是 U2F 设备的软件版本,请查看 mritz_p 的 virtual-u2f,或者在我的原始答案中提到的服务器库的测试套件中使用的软键类。
    猜你喜欢
    • 1970-01-01
    • 2018-12-26
    • 2012-06-28
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 2011-03-30
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多