为了为登录提供更高的安全性,网站正在部署双因素身份验证 (2FA),通常使用智能手机应用程序或短信。这些机制使 网络钓鱼 更难,但无法完全阻止它 - 用户仍然可能被诱骗传递代码,短信也可以通过多种方式被拦截。
Firefox 60 将默认启用 WebAuthn API,提供基于 公钥加密 的双因素身份验证,不受我们今天所知的网络钓鱼的影响。继续阅读以获取介绍,并了解如何保护数百万已经拥有 FIDO U2F USB 令牌 的用户。
创建新凭据
让我们从一个简单的例子开始:这请求一个与标准 USB 连接的 FIDO U2F 设备兼容的新凭据;有许多此类兼容令牌以 Yubikey、U2F Zero 等名称出售
const cose_alg_ECDSA_w_SHA256 = -7;
/* The challenge must be produced by the server */
let challenge = new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]);
let pubKeyCredParams = [{
type: "public-key",
alg: cose_alg_ECDSA_w_SHA256
}];
let rp = {
name: "Test Website"
};
let user = {
name: "Firefox User <firefox@example.com>",
displayName: "Firefox User",
id: new TextEncoder("utf-8").encode("firefox@example.com")
};
let publicKey = {challenge, pubKeyCredParams, rp, user};
navigator.credentials.create({publicKey})
.then(decodeCredential);
对于 USB U2F 令牌,这将使连接到用户系统的所有兼容令牌等待用户交互。一旦用户触碰任何设备,它就会生成一个新凭据,并且 Promise 解析。
用户定义的函数 decodeCredential()
将解码响应以接收密钥句柄,无论是存储在设备上的 ECDSA 密钥对的句柄,还是用一个秘密的、设备特定的密钥加密的 ECDSA 密钥对本身。属于该对的公钥以明文形式发送。
密钥句柄、公钥和签名必须通过后端使用随机挑战进行验证。由于凭据与请求它的网站进行加密绑定,因此如果来源不匹配,此步骤将失败。这防止了为其他网站生成的凭据的重复使用。
密钥句柄和公钥将从现在起与当前用户相关联。WebAuthn API 规定没有浏览器 UI,这意味着网站有责任向用户发出信号,让他们现在连接并注册令牌。
获取现有凭据的断言
下次用户登录网站时,他们将需要证明拥有在上一节中创建凭据的第二个因素。后端将检索密钥句柄并将其与一个新的挑战一起发送给用户。由于 allowCredentials
是一个数组,因此它允许发送多个令牌,如果多个令牌与单个用户帐户注册。
/* The challenge must be produced by the server */
let challenge = new Uint8Array([42,42,33 /* 29 more random bytes generated by the server */]);
let key = new Uint8Array(/* … retrieve key handle … */);
let allowCredentials = [{
type: "public-key",
id: key,
transports: ["usb"]
}];
let publicKey = {challenge, allowCredentials};
navigator.credentials.get({publicKey})
.then(decodeAssertion);
同样,所有连接的 USB U2F 令牌将等待用户交互。当用户触碰令牌时,它将尝试使用给定的 ID 查找存储的密钥句柄,或者尝试使用内部密钥将其解密。成功后,它将返回一个签名。否则,身份验证流程将中止,网站需要重新尝试。
解码后,用于签名的签名和密钥句柄将发送到后端。如果与密钥句柄一起存储的公钥能够使用提供的挑战验证给定的签名,则断言被认为有效,用户将被登录。
第一因素身份验证
Web 身份验证还定义了无需用户名和密码即可使用安全令牌登录的机制,例如智能手机上的受信任执行环境。在这种模式下,您的令牌会证明您不仅拥有它,而且您作为一个人使用密码 (您知道的东西) 和/或生物识别 (您是谁) 解锁了令牌。
在这个世界里,网站可以让你注册,通过在你的智能手机上出现提示并回答提示来执行对桌面上的 Web 应用程序的无缝身份验证。
今天部署的 FIDO U2F 令牌还不够复杂,无法实现这一点,但下一代令牌将可以实现,Web 开发人员将使用 Web 身份验证与这些 FIDO 2.0 令牌进行交互。
WebAuthn,即将在您的 Firefox 附近推出
这是对 Web 身份验证世界的简短介绍,它有意省略了很多细节,例如 CBOR 编码 和 COSE_Key 格式,以及可以传递给 .create()
和 .get()
函数的其他参数。
我们鼓励开发人员开始尝试使用 WebAuthn,并允许用户使用第二个因素来保护其登录,因为 API 变得可用。在撰写本文时,我们不知道任何 WebAuthn-U2F polyfill 库,但希望这些库很快可用。如果您看到了一些有希望的东西,请在评论中告诉我们。
将标准化的双因素身份验证带到 Web 上非常令人兴奋;公钥加密已经通过 TLS 协议保护了我们数据在互联网上的传输,现在我们可以使用它来使网络钓鱼变得更加困难。在 Firefox Nightly 中试用 WebAuthn!
关于测试的最后说明
Web 身份验证是一项强大的功能。因此,它只能在 安全上下文 中使用,如果在框架中使用,则只有当所有框架与父文档来自同一来源时才可以使用。这意味着当您在一些流行的测试网站(如 jsfiddle.net)上尝试使用它时,您可能会遇到安全错误。
关于 J.C. Jones
让人们在网络上安全。Firefox 的密码工程主管。
关于 Tim Taubert
从事 Firefox 和 NSS 的安全工程师。
9条评论