如何使用FIDO U2F允许用户通过我的网站进行身份验证?

时间:2014-10-29 18:07:37

标签: google-chrome authentication fido-u2f

随着最近关于FIDO U2F规范的讨论,我想在测试平台上逐步实施FIDO U2F,为即将推出的最终规范做好准备。

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

现在,我不确定如何在我自己的网站上使用这些东西。我查看了Google的Github页面上的U2F项目,并检查了他们的web app front-end。它看起来很简单(仅限JavaScript)。 那么使用FIDO实现第二个因子auth就像实现一些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;             
      });

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

2 个答案:

答案 0 :(得分:49)

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

您需要了解U2F specifications才能做到这一点。特别是如何实施挑战 - 响应范例以及应用程序和方面如何工作。这在规范中有详细描述。

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

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


在用户使用FIDO U2F令牌进行身份验证之前,他们需要注册。 为了允许他们这样做,您需要在浏览器中调用window.u2f.register。为此,您需要提供一些参数(再次;阅读规范以获取详细信息)。 其中包括挑战和您应用的 id 。对于Web应用程序,此 id 必须是触发FIDO操作的Web页面的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;
};

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

Register Map of a FIDO U2F Registration Response Message

  1. 生成的密钥对的公钥 - 您需要将其存储以供将来进行身份验证。
  2. 生成的密钥对的密钥句柄 - 您还需要将其存储以备将来使用。
  3. 证书 - 您需要检查您是否信任此证书和CA.
  4. 签名 - 您需要检查签名是否有效(即确认与证书一起存储的密钥)以及签名的数据是否是预期的数据。
  5. 我为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;
    };
    

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

    Register Map of a FIDO U2F Authentication Response Message

    1. 您需要确保签名与之前获得的公钥相匹配。
    2. 您还需要验证签名的字符串是否合适。
    3. 执行这些验证后,您可以考虑对用户进行身份验证。服务器端代码的简要示例实现也包含在我的server example

答案 1 :(得分:22)

我最近在 listing all U2F server libraries 上写了这方面的说明,以及developers.yubico.com/U2F(其中大部分捆绑了一个完全正常运行的演示服务器)。目标是使开发人员能够实现/集成U2F,而无需阅读规范。

免责声明:我是Yubico的开发人员。