Web 应用身份验证的未来?WebAuth 介绍

发表于 2年以前  | 总阅读数:836 次

你的密码安全吗

如何判断自己的密码已经泄露?

一些安全厂家会定期收集互联网上被拖库的相关数据账号信息,我使用了Avast提供的一个工具来查询自己的密码是否被泄露(https://www.avast.com/hackcheck/) ,这里只需要输入你的邮箱地址,就能查询到你关联地址的邮箱的登陆账号或者密码是否被泄漏。我在这里输入了我之前比较常用的QQ邮箱账号,可以发现我的密码已经遭到泄漏,泄露的来源分别是Adobe、CSDN和京东。其中Adobe和京东泄露的是加密后的密码,因此还算可控,CSDN泄露的是明文密码,所以非常危险。

如果你使用了Chrome浏览器保存密码,在Chrome的安全设置中,也有提醒你密码已经被泄露的选项。勾选这个选项,在你的密码被泄露时就会给你发出警告。

除此之外,还有一些黑灰产的途径可以查询到自己的密码和个人隐私信息是否被泄露(如Telegram社工库之类的途径),因为涉及到相关法律问题,因此不仔细分享。但是可以得到的结论是:我们的密码并不安全。

为什么你的密码可能不安全

密码是如何存储的

通常情况下,密码都应该在数据库中被加密存储,使用明文存储密码是开发信息系统的大忌,但是事实上,能够做到这一点的信息平台开发商都不多,对于一些“小作坊式”开发的厂家,密码很多情况下都是明文保存的。

对于密码的加密,通常会采用一些Hash算法,在注册账户时,对账号的密码进行Hash计算后,再进行存储,以MD5算法为例:

MD5 ("password") = 5f4dcc3b5aa765d61d8327deb882cf99

若用户的密码为password,在Hash计算后,得到的值为5f4dcc3b5aa765d61d8327deb882cf99,在进行存储时,将得到的Hash值存入数据库的密码字段。

在用户登陆时,只要将用户密码的输入再做一次MD5计算,将得到的Hash值与数据库存储的值进行比较,就可以判断用户的密码输入是否正确了。

这样做的好处是,即使数据库中用户密码的相关信息字段被泄露,用户真正的密码明文是不知道的。这其中利用到了Hash算法的不可逆性:在有限算力的情况下,Hash算法只能从输入得到输出,无法从输出反推得到输入。因为这样的特性,Hash算法通常用在保存密码,信息和文件完整性校验等地方。常用的Hash算法有MD5、SHA、HMAC等。

但是这样的算法也会存在一些问题,虽然无法从输出反推得到输入,但是可以建立一个密码到其哈希值的字典(即彩虹表),在破解时只需要查询彩虹表的值,即可得到对应的密码明文数据。

为了解决这样的问题,我们可以在计算哈希值时采用加盐的方式。对于每个用户,盐值都采用随机数。在计算哈希时,将用户输入的密码和盐值进行组合之后再进行计算,最后将加盐的Hash值存入密码字段。如使用用户的随机UID32142作为盐值,计算方法为:

MD5 ("password32142") = 970e6155f135079c9c1b9d3302b957b5

通过随机加盐的方式,可以有效地避免彩虹表攻击造成密码原文泄露。MD5是一种比较简单的Hash算法,因此在不推荐在实际使用的时候采用MD5算法存储密码,通常情况下我们会有一些更适合密码的哈希算法比如Bcrypt算法来对密码计算Hash,Bcrypt算法在生成时就会生成一段随机的盐值,并且将盐值保存在输出的结果中,这样的好处是即使是同样的输入,得到的输出也是不同的,能够有效避免密码原文泄露的风险。

Bcrypt("password")=10$7ioawRWnYEBZwGE7QAGL0.oa5suk8/NjdAS0RSlqy8Kehplft8CBy

密码过于简单

谈到密码的安全性,首先需要强调的是几条密码保护的基本规则:

  • 不使用个人身份相关的信息作为密码,如生日、手机号码、姓名等任何个人相关的信息,因为这些信息很容易获取;
  • 避免在不同的系统上使用相同的密码,因为一旦有一个系统的密码遭到泄露,那么也意味着你其他平台的密码也遭到了泄露;
  • 避免使用简单的单词或者重复的数字及字母(如password/123456)等,尽量使用大小写字母+数字+符号的组合来作为密码,因为简单规律的密码很容易通过彩虹表等方式破解。
  • 经常替换自己的密码,因为时常会有发生企业被拖库/日志泄露的问题,经常替换密码可以把数据泄露的风险降到最低。

但是实际上对于上述几点,能够完美坚持做到每一点的同学我相信一定不多。大家通常使用的密码都是与自己相关的规律组合,因此存在着一定的隐私泄露的风险。

业务系统存在漏洞

事实上,所有的业务系统都是由人来开发的。但是人并不是机器,因此总是会存在着犯错的可能性,这是无法避免的,我们只能从流程上来规范以尽量降低发生错误的概率。但是就如Meta/Twitter这样的大公司都存在着各种各样的密码泄露的问题,国内的BAT等公司也都曾爆出过密码被泄漏的安全问题。除此之外,还有着XCode Ghost/Docker Hub数据泄露等供应链攻击,就连流程详尽规范的大公司都防不胜防,就更不用说你手机上那些不知名小公司的小App了。

就连我们自己的业务系统也不例外:在某日排查线上bug的时候,我也发现在我们业务使用到的某上游服务中,也有把用户的密码直接明文打印在日志中的行为。根据公司的数据安全管理规定数据分类分级表,用户操作行为日志等属于L3级别数据 ,用户账号的密码等数据属于L4级别数据,因此在日志中,不可以出现用户明文密码相关的敏感字段。这样任何拥有L3级别日志查询权限的用户,都可以获取到L4级别的保密数据,这样的操作相当于把L4级别的数据范围扩大到了L3级别上,因此是违法相关数据保护规定的行为。出现这样的问题可能是无意为之,但是还是暴露了我们在代码安全上的意识还有需要加强的地方。

基础设施/硬件漏洞

对于业务系统产生的一些安全漏洞,我们可以通过一些流程和规范尽量保障,但是对于一些基础设施和硬件的漏洞,就很难能够通过这样方式来预防了,如以下的几个例子:

  • Heartbleed心脏出血漏洞:出现在加密程序库OpenSSL的安全漏洞,该程序库广泛用于实现互联网的传输层安全协议(TLS)。原因是在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检查)。
  • Meltdown漏洞:CPU的硬件漏洞,Intel自1995年发布的开始所有具备非依序执行的CPU产品都有该漏洞。
  • Log4j 远程代码执行漏洞:JNDI服务没有对用户的输入进行过滤,导致可能产生远程代码执行。

上述这样的一些漏洞都会造成服务端的风险,从而产生被黑灰产拖库导致用户密码泄漏的风险。

如何解决密码不安全的问题

总的来说,实现绝对的安全是不可能的,所以我们只能在有限的条件下,寻求相对的安全。为了能够实现这样相对的安全,现有的密码验证方式矛盾的地方在于:安全等于麻烦,为了实现账户的安全,你需要记忆各种复杂的密码和验证方式,要想省事的话就只能使用一些简单方便记忆的密码,并且在不同平台使用相同的密码,这样虽然省事了,但是可能会带来更多的麻烦:密码泄露导致账户被盗造成个人隐私和财产的损失。

怎么解决安全和麻烦这样的问题呢,FIDO(Fast IDentity Online)联盟想出了比较完美的解决方案:

既然密码不安全,那么没有密码不就可以解决密码不安全的问题了吗?

FIDO联盟和W3C为了解决这样的鱼与熊掌的问题,希望可以制定相关的技术规范,定义一套开放的、可扩展的、能互用的机制,减少用户 在认证时对密码的依赖,于是WebAuthn应运而生。

WebAuthn是什么

WebAuthn全称为Web Authentication,是一个使用非对称加密的方式,在Web应用上替代密码/短信验证码等方式在Web应用中进行注册、登陆、双重认证(2FA) 的API。能够解决钓鱼攻击、数据泄漏的安全问题,同时也能提高应用的用户体验(不必记忆复杂的密码)。

通过使用WebAuthn的API,我们可以方便实现指纹、人脸等生物信息的认证或者是加密硬件如USB Key(如网银使用的U盾)、蓝牙设备等来验证身份信息,在方便的同时能够保障安全和隐私。

兼容性

从CanIUse中可以看到,Web Authentication在桌面端浏览器的兼容性较好,绝大多数的桌面端浏览器都能支持,但是在移动端的兼容性较差:iOS仅在14.5以上的版本完全支持,安卓支持Android5以上版本,除此之外,由于依赖TPM模块和指纹/人脸识别等传感器,硬件配置也会影响WebAuthn的可用性。

  • Windows 10 1903 以下版本仅 Edge 能提供完整支持,其他浏览器只能使用 USB Key等外部认证器;1903+ 中所有浏览器都可以使用 WebAuthn(Windows Hello)
  • iOS 13.3 以下的版本不支持 WebAuthn,iOS14.5 以下的版本仅支持外部认证器,iOS 14.5 开始 Safari 已支持全功能 WebAuthn(FaceID/TouchID)

需要注意的是,WebAuthn只能在HTTPS或者localhost中使用,不支持HTTP环境,即只有在保证当前的环境是安全的前提下,WebAuthn的这些实现才是有意义的。

一些概念

2FA

2FA的全称为2 Factor Authentication,即双因子认证,通常是结合密码以及其他标志(如OTP、USB Key、短信验证码、指纹等生物特征)进行认证的方式。现在2FA的使用已经比较普遍,许多厂家会结合风控系统在密码验证的同时结合其他认证方式,保证授权是可信的。比如说在新的设备上登录社交App时,通常除了密码之外,还会需要其他的认证方式。

OTP

OTP即一次性密码(One-time password),OTP的计算通常是基于时间戳的,密码的生成具有有效期(通常是30s)。使用OTP能够有效地避免“重放攻击”,一般的静态密码,在使用时如果设备上有可以监听键盘输入的木马等程序,很容易造成密码的泄露。OTP解决了这样的问题,即保证了泄露的密码也是没有用的(因为只能使用一次,且在极短时间内有效)。通常会在安全性要求比较高的情况下使用:如网游账号(左图,盛大密宝,我小时候玩盛大游戏时,使用到的OTP密码器)或企业认证(右图,Seal VPN)。OTP的缺点在于每次都要打开对应的软件或者相关的OTP设备来获取一次性密码,使用的便捷程度上存在一定的不便。

因为OTP的计算是基于时间戳的,之前我有遇到过一种情况,OTP怎么输入都不对,后来发现是我本地设备的NTP存在问题,没有和NTP Server进行同步导致客户端获取到的时间不对,因此计算得到的OTP也不对。如果下次大家有遇到类似的情况,记得先检查一下本地设备的时间是否正确。

对称加密

对称加密算法的特点是,在加密和解密的过程中,使用的密钥是相同的,因此通讯的双方需要交换并持有相同的密钥。常见的对称加密算法有AES/DES等。

优点:

  • 加密和解密的算法比较简单,因此计算速度要比非对称加密高

缺点:

  • 要求通讯双方持有相同的密钥,存在交换密钥的过程

非对称加密

和对称加密不同的是,在非对称加密中,需要一组密钥对来进行加密和解密。这一组密钥对我们称为公钥(可以公开的密钥)和私钥(需要保密的密钥)。除了在WebAuthn中有用到之外,其他地方也非常常见,比如说JWT/HTTPS(HTTPS既有非对称加密,也有对称加密)/SSH等。非对称加密有这样的一些特点:

  • 公钥和私钥都可以用来加密和解密:即可以用公钥加密,再用私钥解密;也可以使用私钥加密,再用公钥解密,但是这两者的用途通常是不一样的,私钥加密公钥解密的场景一般用来确认身份和防止伪造;而公钥加密私钥解密通常用来保护隐私数据。
  • 可以由私钥推导得到公钥,但是反过来公钥无法得出私钥

常用的非对称加密算法有RSA/ECC等。

优点

  • 不存在私钥交换的过程,因此安全性比对称加密要高

缺点

  • 计算复杂度比对称加密要高,因此速度会略慢于对称加密

WebAuthn

术语

  • 用户(User):指需要验证身份的人,即需要准备登录的你
  • 用户代理(User Agent):指用户使用的客户端,如浏览器或者操作系统,负责和Authenticator交互
  • 认证器(Authenticator):指用来替代密码进行认证的设备,如指纹传感器、蓝牙设备、USB Key等
  • 依赖方(Relying Party):指依赖认证服务方,比如网站系统的服务器
  • 安全密钥(Security Key):通过蓝牙/NFC/USB连接的物理设备
  • FIDO:是一个组织,也是一系列协议标准,FIDO协议是由FIDO联盟开发的一组协议标准:这组协议里面包括了UAF(Universal Authentication Framework)协议、U2F(Universal Second Factor)协议(现在也称为FIDO1协议)和FIDO2协议。
  • FIDO2: 是一种全新的、现代的、简单的、安全的无密码身份认证协议的名称,包含了核心规范WebAuthn(客户端API协议)和CTAP(认证器API协议)
  • CTAP(Client to Authenticator Protocols ):客户端到认证器协议,规范了蓝牙/NFC/USB和身份认证器通信的低级协议。CTAP 系列包括CTAP1和CTAP2协议。
  • CTAP2:CTAP 协议第二版的名称。其主要的特点是使用 CBOR 编码、向后兼容 CTAP1、扩展和新的证明格式。CTAP1和CTAP2共享相同的传输层,因此版本差异主要是数据结构上的差异。
  • Challenge:挑战,通常是一串随机字符串,用于对其进行签名以验证身份是否正确
  • Attestation:证明,在注册时认证器产生的验证数据
  • Assertion:断言,在验证时认证器产生的验证数据
  • Public Key Credential:公钥凭证,认证器产生的凭证,用于替代密码登录

工作原理

FIDO协议原理

我们在这里所指的FIDO协议,通常指UAF/U2F/FIDO2这三种协议中的任意一种,因为这三种协议的工作原理都是类似的,区别只在于结构的不同。FIDO要实现在没有其他信息的情况下证明使用者的身份,需要引入一种零知识证明的方式来解决。FIDO基于一种挑战应答方式(Challenge-Response)机制的方式进行工作:每次认证时,服务端给客户端发送一个随机的挑战字符串,客户端接收到这个挑战后,做出相对应的应答。其工作流程如下:

依赖方(服务端)向客户端发送challenge和凭证 ID,客户端再附加依赖方的信息将其发送给身份认证器。身份认证器会首先检查用户是否存在,然后通过弹窗等请求用户按下按钮或者使用指纹传感器等进行完整的用户身份的认证。验证完成后,身份认证器使用凭证ID所标识的对应私钥对challenge进行加密,再将断言返回给客户端,客户端将相关身份认证器的提供信息转发给依赖方。然后依赖方会检查返回的信息,确保响应包含符合预期的来源和challenge,然后用服务端已经存储的公钥来验证签名。这个工作流中的任何一个环节失败,即说明存在钓鱼攻击等场景,认证就会失败。

Challenge-Response 的认证方式使用非常广泛,很多协议如Kerberos/SSH也采用了类似的方式。

过程

WebAuthn使用的工作流一般分为两种:注册(Registration)和验证(Authentication),注册用来给系统添加用户相关的身份认证信息,验证用来校验和检查用户的身份是否正确。

注册

注册的流程如下:

0⃣️ 浏览器向依赖方发送注册请求:

如点击一个Button开始注册用户,这里的协议和格式都不在WebAuthn 的标准范围之内,可以由客户端自行实现

1.依赖方向浏览器发送挑战、依赖方信息和用户信息:

这里的协议和格式也不在WebAuthn的标准范围内,可以是基于HTTPS的XMLHttpRequest/Fetch实现,也可以使用任意其他协议(如ProtoBuf),只要客户端能够和服务端发送对应的请求消息即可,但是需要保证环境是安全的(HTTPS)

2.浏览器向认证器发送用户信息、依赖方信息和客户端信息的Hash值

在浏览器内部,浏览器将验证参数并用默认值补全缺少的参数,然后这些参数会变为clientDataJSON。调用 create() 的参数与clientDataJSON 的 SHA-256 哈希一起传递到认证器(只有哈希被发送是因为与认证器的连接可能是低带宽的 NFC 或蓝牙连接,之后认证器只需对哈希签名以确保它不会被篡改)

3.认证器请求用户确认,然后创建一对公私钥,用私钥创建证明

在进行这一步时,认证器通常会以某种形式要求用户确认,如输入 PIN、使用指纹、人脸扫描等,以证明用户在场并同意注册。之后,认证器将创建一个新的非对称密钥对,并安全地存储私钥以供将来验证使用。公钥则将成为证明的一部分,被在制作过程中烧录于认证器内的私钥进行签名。这个私钥会具有可以被验证的证书链。

4.认证器把签名和公钥以及凭证ID发送给浏览器

新的公钥、全局唯一的凭证 ID 和其他的证明数据会被返回到浏览器,成为 attestationObject。

5.浏览器将证明数据和客户端信息发送给依赖方

这里和前面一样,可以使用任意的格式或协议,前提是需要保证环境安全

6.依赖方用公钥验证发送的challenge,如果成功则将对应的公钥与用户绑定存储在数据库中,完成注册流程

在这一步,服务器需要执行一系列检查以确保注册完成且数据未被篡改。步骤包括:

  • 验证接收到的挑战与发送的挑战相同;
  • 确保 origin 与预期的一致;
  • 使用对应认证器型号的证书链验证 clientDataHash 的签名和证明;
  • 验证步骤的完整列表可以在 WebAuthn 规范中找到;
  • 一旦验证成功,服务器将会把新的公钥与用户帐户相关联以供将来用户希望使用公钥进行身份验证时使用。

验证

在验证中,浏览器向依赖方发送某个用户的验证请求后的行为如下:

1. 依赖方向浏览器发送挑战

2. 浏览器向认证器发送依赖方ID、挑战和客户端信息的Hash值,

3. 认证器请求用户确认,然后通过依赖方ID找到对应的私钥,使用私钥签名挑战(断言)

4. 认证器将断言信息和签名后发送给浏览器

5. 浏览器将签名、验证器数据以及客户端信息发送给服务器

6.服务器使用用户绑定的公钥验证挑战是否与发送的一致,如果验证通过则表示认证成功

区别

注册和验证之间的主要区别在于:

  • 注册的时候不需要签名
  • 验证不需要用户或信赖方信息
  • 验证使用之前生成的密钥对创建一个断言,而不是使用在认证器在制造过程中烧录的密钥对创建证明

浏览器API

要使用 WebAuthn,需要先了解Credentials Management API,因为Web Authn API继承自Credentials Management API。Credentials Management API允许网站与用户代理的密码系统进行交互,以便网站能够以统一的方式处理站点凭证,而用户代理为凭证管理提供更好的帮助。通常用来存储和检索用户、联合账户凭证(FederatedCredential,如OpenID Connect)、和非对称密钥对凭证(WebAuthn使用的就是非对称密钥对的凭证)。

注册:navigator.credentials.create(options)

通过这个API,使用publicKey选项时, 创建一个新的凭据,无论是用于注册新账号还是将新的非对称密钥凭据与已有的账号关联。其中options的结构如下:

const options = {
  publicKey: {
    rp: {
        id: "example.com",
        name: "example.com",
    },
    user: {
      name: "username@example.com",
      id: userIdBuffer,
      displayName: "User Name",
    },
    pubKeyCredParams: [
        { type: "public-key", alg: -7 }
    ],
    challenge: challengeBuffer, 
    authenticatorSelection: { authenticatorAttachment: "platform" },
  },
}
  • rp: 依赖方

  • id?(String):依赖方的ID,当前域名或其上级域名,不指定则默认当前页面域名

  • name(String):依赖方的名称

  • user:用户信息

  • id(Uint8Array):用户ID,不得包含任何用户信息。

  • name(String):当前登录的用户名,可以包含电子邮件、用户名、电话号码等认为是主要用户标识符的任何内容。

  • displayName(String):用来显示用户的名称,具体的显示行为取决于用户代理

  • pubKeyCredParams(Array):公钥算法的list,指明依赖方可以接受哪些加密算法

  • type(String):"public-key"

  • alg(Number):算法的类型,一个整数,枚举值可以参考这里,上面的-7为ES256算法。目前,FIDO2 服务器必须支持 RS1、RS256、ES256 和 ED25519。

对于 pubKeyCredParams,通常我们只需添加 ES256 (alg: -7) 算法即可兼容大部分外部认证器,此外,再添加 RS256 (alg: -257) 算法即可兼容大部分平台内置认证器(如 Windows Hello/TouchID)。前端添加算法之后,后端也需要相应的算法支持进行签名校验。

  • authenticatorSelection?:用于过滤想要使用的认证器

  • "preferred"

  • "required"

  • "discouraged"

  • "preferred":依赖方希望有用户本人验证,但是也可以接受用户在场

  • "required":依赖方要求用户本人验证

  • "discouraged":依赖方不关心用户验证

  • "platform":仅接受平台内置的认证器,如TouchID/FaceID

  • "cross-platform":仅接受外置跨平台的认证器,如USB Key

  • authenticatorAttachment?:"platform" | "cross-platform"

  • userVerification?:指定认证器是否需要验证“用户为本人”,否则只须“用户在场”。具体验证过程取决于认证器(不同认证器的认证方法不同,也有认证器不支持用户验证),而对验证结果的处理情况则取决于依赖方。该参数可以为以下三个值之一:

  • residentKey?:客户端密钥驻留,创建可发现凭证的选项,用于实现无用户名登录

  • excludeCredentials?(Array): 包含已向用户注册的凭据列表。然后将此列表提供给验证器,如果验证器识别其中任何一个,它会取消操作并返回错误 CREDENTIAL_EXISTS,从而防止同一验证器的重复注册。数组中的每一项都是一个公钥凭证对象,包含以下属性:

  • "internal" :平台内置的认证器

  • "ble":蓝牙连接的认证器

  • "nfc":NFC连接的认证器

  • "usb":USB连接的认证器

  • type(String):值只能为"public-key"

  • id(Uint8Array):需要排除的凭证ID

  • transports?(String[]):指定认证器和用户代理的通讯方式,可以是以下的取值

  • timeout?(Number)

const publicKeyCredential = await navigator.credentials.create(options);

调用完创建凭证的API后,浏览器会弹出一个认证器的选择弹窗(具体取决于authenticatorAttachment 这个字段的设置,如果指定了可能就不会有认证器选择弹窗的这个环节),在这个弹窗中,用户可以选择使用哪个认证器来生成凭证:

以选择“本设备”为例,会调用系统内置的认证器(在macOS上即表现为使用Touch ID/Windows上为Windows Hello)进行认证:

使用指纹认证成功后,WebAuthn API会通过Promise返回PublicKeyCredential对象,包含其对应的公钥凭证信息如下:

PublicKeyCredential的结构如下:

  • rawId(ArrayBuffer):凭证ID,依赖方通过在允许列表中提供的凭据来识别设备上的凭据
  • id(String):base64url编码的rawId
  • type(String):"public-key"
  • authenticationAttachment: 和上面介绍的一致,验证器的类型
  • response:响应,认证器的结果,包含凭证创建和证明信息
  • attestationObject(ArrayBuffer):CBOR格式编码的证明结构

CBOR是一种提供良好压缩性,扩展性强,不需要进行版本协商的二进制数据交换形式。

其字段结构定义如下:- rpIdHash:依赖方ID的SHA-256哈希值,32bytes

  • flags:标志位
  • signCount:签名计数
  • ED:是否有扩展数据
  • AT:是否有attestedCredentialData
  • 0:保留位
  • UV:用户是否已验证
  • UP:用户是否在场
  • none:无证明
  • packed:为WebAuthn专门优化的证明, 使用一种非常紧凑但仍可扩展的编码方法
  • tpm:TPM芯片使用的格式
  • android-safetynet:Android使用的格式
  • android-key:Android使用的格式
  • fido-u2f:FIDO U2F 认证器使用的格式
  • fmt:证明的格式
  • authData:证明数据:包含公钥、凭证id等信息

认证器应实现签名计数器功能。这些计数器在概念上认证器为每个凭据存储,或为整个认证器全局存储。凭据的签名计数器的初始值在认证器注册返回的认证器数据的值中指定。对于每个成功的认证器验证操作,签名计数器都会递增一些正值,并且后续值将再次返回到认证器数据中的 WebAuthn 信赖方。签名计数器的目的是帮助信赖方检测克隆的认证器。克隆检测对于保护措施有限的认证器更为重要。

信赖方存储最新认证器验证操作的签名计数器。(或者来自认证器的计数器注册操作,如果没有认证器验证曾经对凭据执行过。在后续认证器验证操作中,信赖方将存储的签名计数器值与断言的认证器数据中返回的新值进行比较。如果任一值为非零,并且新值小于或等于存储的值,则可能存在克隆的认证器,或者认证器可能出现故障。

  • attestedCredentialData

  • aaguid:Authenticator Attestation GUID,认证器的GUID

  • credentialIdLength:credentialId的长度

  • credentialId:凭证ID,即上文的rawId

  • credentialPublicKey:CBOR编码的COSE格式的凭证公钥

  • extensions:扩展数据

  • attStmt:证明对象,具体格式和fmt有关

  • clientDataJSON(ArrayBuffer):字段定义如下

{
     "type": "webauthn.create" | "webauthn.get"
     "challenge": "把服务端传输过来的challenge字符串进行base64编码"
     "origon": "https://test.example.com", // 请求源,依赖方域名
     "crossOrigin":  false, //"是否为跨源调用的信息"
 }

其中最重要的参数之一是 origin,它是 clientData 的一部分,同时服务器将能在稍后验证它。

实际上在默认情况下,注册时认证器并不会对挑战进行签名(首次使用时信任模型),attestationObject 并不会包含签名后的挑战。只有依赖方明确要求证明且用户同意后认证器才会对挑战进行签名(具体实现据情况会有所不同)。

得到上面的数据后,我们需要把上面的数据回传给依赖方即后端进行校验,后端的操作至少如下:

1.校验rpIdHash

2. 检查 UV 和 UP

3. 存储证明的计数

4. 存储公钥

验证:**navigator.credentials.get(options)**

这个API也需要传入一个options对象,options的结构和注册的时候比较类似:

const options = {
  publicKey: {
      challenge: challengeBuffer, // 
      rpId: '',
      userVerification: '',
  }
}
  • challenge: 和上面一样

  • rpId?:依赖方ID,域名,和上面的rp.id规则一样

  • userVerification:和上面一样

  • allowCredentials?(Array):使用用户帐户注册的凭据标识符列表。此列表将发送到所有可用设备。如果验证器能够识别列表中的凭证,它将通过提示用户操作(例如按下按钮或指纹)来启动断言生成过程。如果认证器无法识别凭证,它将返回错误,从而通知平台它不是正确的设备。第一个成功的设备结果将完成获取断言请求。数组中的每一项都是对象,包含以下属性:

  • type(String):"public-key"

  • id(Uint8Array):允许的凭证ID

  • transports?(String[]):指定认证器和用户代理的通讯方式,和上面一样

  • timeout?:和上面一样

和create方法一样,调用get这个方法也会返回一个Promise,可以得到认证器返回PublicKeyCredential的对象,结构如下:

  • rawId(ArrayBuffer):ArrayBuffer原始凭证ID
  • id(String):base64url编码的rawId
  • type(String):"public-key"
  • response:响应,认证器的结果,包含凭证创建和证明信息
  • clientDataJSON(ArrayBuffer):和上面一样
  • authenticatorData(ArrayBuffer):认证器信息

认证器的信息和上方的attestedCredentialData的数据结构类似,只是这里不包含公钥的信息了。

  • signature(ArrayBuffer):被认证器签名的 authenticatorData + clientDataHash(clientDataJSON 的 SHA-256 hash)
  • userHandle(ArrayBuffer):create() 创建凭证时的 user.id,这个值不一定会有,取决于create时可发现凭据的设置和user.id的设置

得到这些后,我们只要把PublicKeyCredential对象的内容发送给依赖方即服务端验证即可,依赖方至少要做这样一些的校验:

1.验证 rpIdHash

2.检查 UV 和 UP

3.验证签名的计数,并更新数据库中签名的计数

4.公钥校验签名

可发现凭据

实现完上述的流程后,我们就可以使用指纹等进行登录了,但是这时我们还是会需要使用到用户名,然后才能进行身份认证。如何在不输入用户名的情况下进行认证呢?许多验证器提供了这个功能,我们称为可发现凭据(Discoverable Credentials)。

为什么普通的 WebAuthn 为什么不能实现无用户名登录?大部分认证器为了实现无限对公私钥,会将私钥通过加密后包含在凭证 ID 中发送给依赖方,这样认证器本身就不用存储任何信息。不过,这就导致需要身份认证时,依赖方必须通过用户名找到对应的凭证 ID,将其发送给认证器以供其算出私钥。要不输入用户名,则需要认证器将私钥在自己的存储中也存储一份。这样,依赖方无需提供凭证 ID,认证器就可以通过依赖方 ID 找到所需的私钥并签名。因此这个特性需要认证器能够储存用户ID,即上面的userHandle字段。

为了实现安全隔离,认证器的存储通常会和平台隔离,拥有独立的存储空间(如在Mac平台下,TouchID有独立的安全芯片T1/T2,运行独立的操作系统BridgeOS),一般情况下认证器能够永久存储的私钥数量是有限的,所以只有在真正需要需要无用户名登录时才启用这个特性

实现:

  • create(options)
const options = {
    publicKey: {
        ...options.publicKey,
        authenticatorSelection: {
            ...options.publicKey.authenticatorSelection,
            residentKey: "required",     // 设置为required
            userVerification: "required" // 设置为required
        }
    }
}
  • get(options)
const options = {
    publicKey: {
        ...options.publicKey,
        userVerification: "required", // 设置为required
        allowCredentials: [],         // 设置为空
    }
}

参考资料

[1] MDN: Web Authentication API

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Authentication_API

[2] W3C文档:Web Authentication API Spec

https://www.w3.org/TR/webauthn-3/

[3] WebKit 文档:Meet Face ID and Touch ID for the web

https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/

[4] Medium: Introduction to WebAuthn API

https://medium.com/webauthnworks/introduction-to-webauthn-api-5fd1fb46c285

[5] 谈谈WebAuthn

https://flyhigher.top/develop/2160.html

[6] WebAuthn介绍与使用

https://obeta.me/posts/2019-03-01/WebAuthn%E4%BB%8B%E7%BB%8D%E4%B8%8E%E4%BD%BF%E7%94%A8

[7] WebAuthn Guide

https://webauthn.io/

[8] Apple 安全隔离介绍

https://support.apple.com/zh-cn/guide/security/sec59b0b31ff/web

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/6jkU_hXA8PZT5ism58q9mA

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237269次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8108次阅读
 目录