WebAuthn:更好地保护线上敏感信息

news2024/11/18 10:48:59

1. 引言

2023年知乎博客 WebAuthn: 真正的无密码身份认证 总结得很赞。

在数字时代,密码已成为人们日常生活和在线活动中不可或缺的一部分。尽管互联网已经发展了 20 多年,许多方面都有了巨大的改进,但只有密码,还是 20 年前的用法。

更准确的说,它的用户体验比 20 年前更差了。密码的强度现在要求越来越高,一般不能少于 8 个字符,还要包括特殊符号。另外,除了密码,通常还有其他验证(短信、图片识别、OTP 一次性密码等等)。

然而,即使变得如此麻烦,依然不能杜绝密码被盗、被破解、被钓鱼的风险。

通常,恶意用户与银行帐户、社交媒体帐户和其他敏感数据之间的唯一联系就是密码。
对于用户和开发人员来说,密码带来的相关问题越来越多。用户必须担心密码被网络钓鱼工具窃取,或者如果他们拥有帐户的网站受到威胁,他们的密码会在网上泄露。他们必须担心在没有专用密码管理工具的情况下创建和记住密码。开发人员必须担心通过系统传递密码并将其安全存储在数据库中的所有复杂性。

当前,与黑客相关的违规行为,有81%是利用了被盗或弱密码。

基于密码的身份验证的主要弱点之一是密码是共享秘密。密码是证明”你确实是你“的唯一密钥。如果黑客设法窃取它,他们就可以完全冒充你,除非你使用双因素身份验证的 28% 用户之一。

为了解决这些问题,WebAuthn 应运而生。

目前,越来越多的服务已经开始正式支持 WebAuthn。就在2023年 5 月,谷歌和微软同时宣布全面接入 WebAuthn,支持无密码登录。GitHub 也在几天前宣布开始公测无密码登录功能。

2. WebAuthn简介:公钥加密和 Web 身份验证

WebAuthn,全称 Web Authentication,是由 FIDO 联盟(Fast IDentity Online Alliance)和 W3C(World Wide Web Consortium)联合制定的一套新的身份认证标准,旨在为网络身份验证提供一种更强大、更安全的方式,使用户能够使用他们的设备(如手机、USB 密钥或生物识别器)来进行身份验证,而无需使用密码。该标准于 2019 年 3 月 4 日正式成为 W3C 的推荐标准。目前主流的浏览器已经支持 WebAuthn,包括 Chrome、Firefox、Edge 和 Safari,更详细的支持情况可以通过 https://webauthn.me/browser-support 查看。

为网站创建私钥-公钥对(称为凭据),而不是密码。私钥安全地存储在用户的设备上;公钥和随机生成的凭证 ID 被发送到服务器进行存储。然后,服务器可以使用该公钥来证明用户的身份。

公钥不是秘密的,因为如果没有相应的私钥,它实际上是无用的。服务器不接收任何秘密的事实对用户和组织的安全具有深远的影响。数据库对黑客不再那么有吸引力,因为公钥对他们来说没有用处。

注:FIDO 联盟是一个非营利性组织,由 Google、微软、苹果、三星、高通、芯片厂商、支付公司、银行、电信运营商、认证公司等组成,旨在为用户提供更安全、更简单的身份验证体验。

2.1 Web身份验证依赖

Web身份验证依赖三大属性:

  • 1)强安全:身份验证最好由硬件安全模块支持,该模块可以安全地存储私钥并执行 WebAuthn 所需的加密操作。
  • 2)限定范围:密钥对仅对特定来源有用,如浏览器 cookie。在“webauthn.guide”注册的密钥对不能在“evil-webauthn.guide”使用,从而减轻了网络钓鱼的威胁。
  • 3)已认证:身份验证器可以提供证书,帮助服务器验证公钥确实来自他们信任的身份验证器,而不是欺诈来源。

3. WebAuthn工作原理

WebAuthn 的原理并不复杂,它的核心是基于公钥的加密技术。在 WebAuthn 中,用户的身份认证是通过公钥和私钥来实现的。这很像我们平常使用配置了公私钥的 SSH 登录服务器的过程,只不过 WebAuthn 是在浏览器中实现的。

3.1 WebAuthn组成部分

WebAuthn 由以下三个组成部分组成:

  • 1)用户代理(User Agent):用户代理是指浏览器或者其他支持 WebAuthn 的客户端,它负责与用户进行交互,收集用户的身份认证信息,并将其发送给服务器。
  • 2)身份验证器(Authenticator):身份验证器是指用于生成公钥和私钥的设备,如手机、USB 密钥或生物识别器。Windows Hello 和 macOS 的 Touch ID 也都是常见的身份验证器。
  • 3)Relying Party:Relying Party 是指需要进行身份认证的网站或应用程序,它负责生成挑战(Challenge)并将其发送给用户代理,然后验证用户代理发送的签名结果。

上述三者在两个不同的用例(注册和认证)中协同工作,如下图所示。图中的各个实体之间的所有通信都由用户代理(通常是Web浏览器)处理。
在这里插入图片描述

3.2 WebAuthn的注册流程

在这里插入图片描述
在注册时,用户端会生成一对公钥和私钥。其中,私钥存储在本地,而公钥则发送给服务器,服务端会将公钥与用户账户进行关联。详细的流程如下图所示:
在这里插入图片描述

3.3 WebAuthn的认证流程

在这里插入图片描述
在认证时,用户端会使用私钥对服务器端发送的挑战(Challenge)进行签名,然后将签名结果发送给服务器。服务器端会使用公钥对签名结果进行验证,从而完成身份认证。详细的流程如下图所示:
在这里插入图片描述
可在 https://webauthn.me/ 上体验 WebAuthn 的注册和认证过程。

4. WebAuthn API

WebAuthn 主要涉及2个 API:

  • 1)navigator.credentials.create():用于在注册阶段生成公钥和私钥。注册示例用法为:
    const res = await navigator.credentials.create({
        publicKey: {
          // 随机的、加密安全的、至少 16 个字节的数据
          // challenge: 挑战是在服务器上生成的加密随机字节的缓冲区,并且需要防止“重放攻击”。
          challenge: base64url.decode("<%= challenge %>"),
          // relying party 的信息
          // rp: 这代表“依赖方”;它可以被视为描述 负责注册和验证用户的组织。 必须id是浏览器中当前域的子集。 
          rp: {
            name: "Awesome Corp", // Relying party 的名称
          },
          // user: 这是有关当前注册用户的信息。 身份验证器使用id将凭证与用户相关联。建议不要使用个人识别信息作为id,因为它可能存储在身份验证器中。
          user: {
            id: base64url.decode("<%= id %>"),
            name: "<%= name %>",
            displayName: "<%= displayName %>",
          },
          // authenticatorSelection: 此可选对象可帮助依赖方对允许注册的身份验证器类型进行进一步限制。在此示例中,我们表明我们想要注册一个cross-platform身份验证器(如 Yubikey),而不是像 Windows Hello 或 Touch ID 这样的身份验证器 。
          authenticatorSelection: { userVerification: "preferred" },
          // attestation: 从验证器返回的证明数据包含可用于跟踪用户的信息。 此选项允许服务器指示证明数据对此注册事件的重要性。值"none"表示服务器不关心证明。值"indirect"表示服务器将允许匿名证明数据。direct表示服务器希望接收来自验证者的证明数据。
          attestation: "direct",
          // pubKeyCredParams: 这是一个对象数组,描述服务器可以接受哪些公钥类型。 这是COSEalg注册表中描述的号码;例如,表示服务器接受使用 SHA-256 签名算法的椭圆曲线公钥。
          pubKeyCredParams: [
            {
              type: "public-key",
              alg: -7, // "ES256" IANA COSE Algorithms registry
            },
          ],
        },
      });
    
    // 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
    const json = publicKeyCredentialToJSON(res);
    // 将 json 发送给服务器
    await post("/webauthn/register", {
        state: "<%= state %>",
        provider: "<%= provider %>",
        res: JSON.stringify(json),
    });
    
  • 2)navigator.credentials.get():用于在认证阶段对服务端的挑战(Challenge)进行签名。登录示例用法为:
    const res = await navigator.credentials.get({
        publicKey: {
          // 随机的、加密安全的、至少 16 个字节的数据
          // challenge: 与注册期间一样,这必须是在服务器上生成的加密随机字节。
          challenge: base64url.decode("<%= challenge %>"),
          allowCredentials: [
            {
              // id: 新生成的凭证的ID;它将用于 在对用户进行身份验证时识别凭证。此处提供的 ID 作为 base64 编码的字符串。
              id: base64url.decode("<%= id %>"),
              type: "public-key",
            },
          ],
          // timeout: 在返回错误之前用户必须响应注册提示的时间(以毫秒为单位) 。
          timeout: 15000, // 超过 15 秒未完成认证,则认为认证失败
          authenticatorSelection: { userVerification: "preferred" },
        },
      });
    
    // 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
    const json = publicKeyCredentialToJSON(res);
    // 将 json 发送给服务器
    post("/webauthn/authenticate", {
        state: "<%= state %>",
        provider: "<%= provider %>",
        res: JSON.stringify(json),
    });
    

参考资料

[1] 2023年知乎博客 WebAuthn: 真正的无密码身份认证
[2] WebAuthn官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1571042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】--- 探索栈和队列的奥秘

关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა &#x1f4a1;个人主页&#xff1a;9ilk &#x1f4a1;专栏&#xff1a;数据结构之旅 上回我们学习了顺序表和链表&#xff0c;今天博主来讲解两个新的数据结构 — 栈和队列 &#xff0c; 请放心食用 文章目录 &#x1f3e0; 栈&#x1…

牛客 2024春招冲刺题单 ONT102 牛牛的果实排序【simpe 要知道如何判断是否是质数 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/975a263e2ae34a669354e0bd64db9e2a 核心 需要牢牢记住下面的代码//判断是否为质数public boolean isPrime(int n){if(n1) return false;if(n2 || n3) return true;if(n%6!1 && n%6!5) return false; /…

C++(语法以及易错点2)

1.内联函数 1.1 概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调 用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 ​int ADD(int a,int b) {return ab; }​ 1.2 特性 1. inline是一种以空间换时间…

spring security6重写登陆验证

spring security的认证流程 2. 从文档上可以看出来&#xff0c;UsernamePasswordAuthenticationFilter和AuthenticationManager是认证的关键步骤&#xff0c;/login传过来的username和password由UsernamePasswordAuthenticationFilter接收处理成UsernamePasswordAuthenticatio…

设计模式总结-组合模式

组合设计模式 模式动机模式定义模式结构组合模式实例与解析实例一&#xff1a;水果盘实例二&#xff1a;文件浏览 更复杂的组合总结 模式动机 对于树形结构&#xff0c;当容器对象&#xff08;如文件夹&#xff09;的某一个方法被调用时&#xff0c;将遍历整个树形结构&#x…

基于SSM的品牌银饰售卖平台(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的品牌银饰售卖平台&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring …

LeetCode - 边积分最高的节点

2374. 边积分最高的节点 这是一个有向图&#xff0c;且每个节点都只有一条出边&#xff0c;指向0的边有1&#xff0c;2&#xff0c;3&#xff0c;4 10&#xff0c; 指向7的有5&#xff0c;6 11. 我们只需要一次遍历就可以解决&#xff0c;先搞一张哈希表&#xff0c;k存节点…

docker安装nacos,单例模式(standalone),使用内置的derby数据库,简易安装

文章目录 前言安装创建文件夹docker指令安装docker指令安装-瘦身版 制作docker-compose.yaml文件查看页面 前言 nacos作为主流的服务发现中心和配置中心&#xff0c;广泛应用于springcloud框架中&#xff0c;现在就让我们一起简易的部署一个单例模式的nacos&#xff0c;版本可…

Qt+OpenGL-part3

1-4EBO画矩形_哔哩哔哩_bilibili 可以绘制两个三角形来组成一个矩形&#xff08;OpenGL主要处理三角形&#xff09; 直接画两个三角形&#xff1a; #include "openglwidget.h" #include <QDebug>unsigned int VBO,VAO; unsigned int shaderProgram;//顶点着…

快排序解读

排序算法是计算机科学中不可或缺的一部分&#xff0c;它们在各种数据处理场景中发挥着关键作用。在众多排序算法中&#xff0c;快速排序以其高效的性能和简洁的实现成为了许多程序员的首选。今天&#xff0c;我们就来深入剖析快速排序算法&#xff0c;了解其原理、实现方式以及…

【【萌新的Pytorch入门之Python的学习】】

学习记录 - 参考记录来自B站up主 -爆肝杰哥 ① NumPy 包为 Python 加上了关键的数组变量类型&#xff0c;弥补了 Python 的不足&#xff1b; ② Pandas 包在 NumPy 数组的基础上添加了与 Excel 类似的行列标签&#xff1b; ③ Matplotlib 库借鉴 Matlab&#xff0c;帮 Python 具…

mysql 基本查询

学习了mysql函数&#xff0c;接下来学习mysql基本查询。 1&#xff0c;基本查询语句 MySQL从数据表中查询数据的基本语句为SELECT 语句。SELECT语句的基本格式是&#xff1a; SELECT (*I <字段列表>} FROM <表1>,<表2>..[WHERE<表达式> [GROUP BY <…

C++入门(以c为基础)——学习笔记2

1.引用 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间。在语法层面&#xff0c;我们认为它和它引用的变量共用同一块内存空间。 可以取多个别名&#xff0c;也可以给别名取别名。 b/c/d本质都是别名&#…

QA测试开发工程师面试题满分问答3: python的深拷贝和浅拷贝问题

在 Python 中&#xff0c;深拷贝&#xff08;deep copy&#xff09;和浅拷贝&#xff08;shallow copy&#xff09;是用于创建对象副本的两种不同方式。 浅拷贝是创建一个新的对象&#xff0c;该对象与原始对象的内容相同&#xff08;包括内部嵌套对象的引用&#xff09;&…

SSM框架学习——了解Spring与Eclipse创建Maven项目

了解Spring 什么是Spring Spirng是分层的JavaSE/EE全栈轻量级开源框架&#xff0c;以控制反转IoC和面向切面编程AOP为内核&#xff0c;使用基本的JavaBean来完成EJB的工作。 Spring框架采用分层架构&#xff0c;它的一些列功能被分为若干个模块。 上图中的红色背景模块为本…

提示工程概要

提示工程 1. 两大原则 原则 1&#xff1a;编写清晰具体的说明 使用分隔符 三引号&#xff1a;“”"三个反引号&#xff1a;三个破折号&#xff1a;—尖括号&#xff1a;<>XML标签&#xff1a; 要求结构化输出 HTMLJSONXMLPython字典 检查条件是否满足 检查执行…

C++ 类和对象(初篇)

类的引入 C语言中&#xff0c;结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。 而为了区分C和C我们将结构体重新命名成class去定义 类的定义 标准格式&#xff1a; class className {// 类体&#xff1a;由成员函…

linux安装和使用Rancher

linux安装和使用Rancher Rancher介绍请看如下博客 arm架构安装Rancher并导入k8s集群解决Error: no objects passed to apply 华为云arm架构安装k8s(kubernetes) linux下安装Rancher Rancher部署监控k8s集群状态等,比Dashboard插件强大 提前安装好K8S 在master上执行#如果…

学习心得1

这时我第一次更学习心得&#xff01;不足的在评论区指教。 首先先来分享一下&#xff0c;刷一维数组题目的方法。 仔细读题&#xff0c;不会做的题目先完成输入输出。不要干等着着急&#xff0c;就跳到下一题。如果使用的时oj&#xff0c;那就没有题解但是使用洛谷、LeetCood…

【热门话题】计算机视觉入门:探索数字世界中的“视觉智能”

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 计算机视觉入门&#xff1a;探索数字世界中的“视觉智能”摘要正文一、计算机视…