系统安全之身份认证

本篇我们对常用的身份认证协议做简要的梳理,包括主流的 HTTP 相关认证协议以及证书密钥对、新兴的 WebAuthn 认证。

HTTP 协议认证

RFC 7235 中定义了 HTTP 协议的认证框架,要求在支持 HTTP 协议的服务器,如果访问服务的身份验证失败,需要返回 401 Unauthorized 或 407 Proxy Authentication Required 状态码,并告知客户端应该采用何种方案提供凭证信息,收到响应后客户端按要求加入认证凭据信息后才能继续访问。

# 响应头
WWW-Authenticate: <认证方案> realm=<保护区域的描述信息>
Proxy-Authenticate: <认证方案> realm=<保护区域的描述信息># 请求头
Authorization: <认证方案> <凭证内容>
Proxy-Authorization: <认证方案> <凭证内容>

整个认证流程如下:

在上述认证框架的基础上,HTTP 提出了不同的认证方式。

HTTP Basic & 摘要认证

RFC 2617 提出了 Basic 和 Digest Access(摘要认证)两种方式,我们先来看下 Basic,其认证流程如下:

  • 将用户名密码用冒号间隔做拼接,格式为 username:password
  • 对拼接后的字符串进行 Base64 编码,比如 Base64(admin:12345) 得到 YWRtaW46MTIzNDU=
  • 将编码后的字符串添加 Basic 标识后放到 HTTP 头 Authorization 中,最终结果为 Authorization: Basic YWRtaW46MTIzNDU=,然后向服务端请求。
  • 如果认证通过,则返回 200 响应码。否则按照上述框架要求的,响应 401 并且返回响应头 WWW-Authenticate: Basic realm="Dev", charset="UTF-8"

可以看到 Basic 认证对密码只是做了编码,并没有加密处理,因此使用 Basic 认证时必须结合 TLS 加密传输一起使用。Basic 更多用于系统内部之间一些组件的访问,在实际生产系统中很少使用。

RFC2069 提出了 Digest Access 摘要认证,后续由 RFC 2617 做了一系列的增强,算是对 Basic 的改进,其认证流程如下:

  • 认证失败,服务端返回 401 以及 WWW-Authenticate 头如下。
WWW-Authenticate: Digest realm="testrealm@host.com",qop="auth,auth-int",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",opaque="5ccc069c403ebaf9f0171e9517f40e41"

如果没有特殊要求,其计算的流程如下:

HA1 = MD5(username:realm:password)
HA2 = MD5(method:digestURI)
response = MD5(HA1:nonce:HA2)

其中,nonce 是服务端返回的盐值,method 是请求方法,digestURI 为请求 URI。RFC 2617 提出了
qop(quality of protection,保护质量) 对计算方式提出了更复杂的要求,改进后的计算流程如下:

  • 客户端生成自己的盐值,然后做哈希操作 HA1 = MD5(MD5(username:realm:password):nonce:cnonce)

  • 如果 qop 包含了 auth-init,则 HA2 = MD5(method:digestURI:MD5(entityBody)),entityBody 代表整个请求体。

  • 最后response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)。计算完成后客户端将值加入到 Authorization 请求头中,示例如下:

GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="Mufasa",realm="testrealm@host.com",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",uri="/dir/index.html",qop=auth,nc=00000001,cnonce="0a4f113b",response="6629fae49393a05397450978507c4ef1",opaque="5ccc069c403ebaf9f0171e9517f40e41"

可以看到摘要认证通过盐值、MD5 哈希的方式对用户名密码传输做了一定程度的加密,但其实最终加密后的强度还是取决于密码的强度,如果密码强度较弱其依然有泄露的风险,另外这里也没有办法避免中间人攻击。

Bearer(OAuth 2.0)认证

RFC 6750 描述了基于 OAuth 2.0 的认证授权方式,它要求使用 Bearer Token(承载令牌) 的方式进行认证。

客户端在获取令牌成功后,需要将令牌放到 Authorization 请求头中,格式如下:

Authorization: Bearer <token>

OAuth 2.0 协议当初主要是为了对第三方授权而实现的,其同时设计身份认证和授权,这个我们后面在详细介绍。

Form 认证

因为身份认证通常是应用系统的业务逻辑的一部分,虽然 HTTP 协议提供了基本的认证框架,但在大多数情况下,我们需要自行实现认证流程。最常见的方式就是通过 HTML 表单提交用户名和密码,然后服务端验证成功后返回一个凭据给客户端,客户端在后续的请求中将凭据放到 HTTP 请求头中。这在万维网中被称为 Web 认证,因为最常见的方式就是通过表单登录,也叫做表单认证(Form-based Authentication)。

表单认证并没有一个标准的规范规范,因此通常由产品和工程师根据业务需求自行设计实现,在设计方案时可以参考 OWASP Authentication Cheat Sheet 中的建议。

Web WebAuthn 认证

证书密钥对

上述认证方式都是基于用户名密码或者用户生物特征等方式进行认证的,这在ToC(面向消费者)场景下是比较常见的方式,但在其他场景下,比如系统内部的服务间通信、API 调用,机构和机构之前的通信,则需要其他的解决方案。最常用的就是数字证书和密钥对认证。

通过非对称加密的方式,我们可以生成公钥和私钥,我们将私钥安全保存,然后将公钥分发出去。通过私钥加密的数据只有使用公钥才能解密,这样同时解决了身份认证和数据加密的问题。但这种方式无法避免中间人攻击,因此通常需要结合数字证书来使用。

我们需要一个权威证书机构(CA,Certificate Authority)来颁发证书,证书中包含了公钥和一些其他信息,比如证书的有效期、颁发者等。通信双方在拿到证书后,可以向 CA 机构验证证书的合法性,验证通过后就可以使用公钥进行加密通信,从而保证通信的安全性。

目前网站和应用系统中使用的 HTTPS 通信以及云原生的下的 mTLS(双向 TLS)认证都是基于证书密钥对的方式。

传统网站的 HTTPS 单向认证流程如下:

  1. 我们在浏览器访问网站,发起 HTTPS 请求。
  2. 服务端收到请求后,返回自己的证书给浏览器。
  3. 浏览器验证证书的合法性,如果合法则继续请求,否则返回错误。
  4. 浏览器使用证书中的公钥加密请求数据,并发送给服务端。

可以看到这里主要是浏览器客户端去验证服务端的证书是否合法,也就是验证我们访问的网站是否是真实合法的。而在 mTLS 双向认证中,除了客户端验证服务端的证书外,服务端也会验证客户端的证书是否合法,流程如下:

  1. 客户端请求服务端
  2. 服务端返回其 TLS 证书
  3. 客户端验证服务端证书合法性
  4. 客户端提供其 TLS 证书
  5. 服务端验证客户端证书合法性
  6. 验证成功,双方使用各自的公钥进行加密通信。

在云原生环境以及 Zero Trust 安全架构理念的指导下,mTLS 几乎已经成为服务间通信的的必备安全认证方式。通常在企业内部,我们可以通过自签名证书的方式来生成 CA 和证书密钥对,下面我们用 OpenSSL 命令工具来演示这个过程:

  • 生成 CA 私钥和证书
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt
  • 生成服务端私钥和证书签名请求(CSR)
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
  • 生成服务端证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256
  • 生成客户端私钥和证书签名请求(CSR)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
  • 生成客户端证书
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256

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

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

相关文章

部署http服务

使用flask搭建一个http服务&#xff0c;能够通过本地的另外一个终端访问对应接口&#xff0c;拿到服务端的计算结果 服务端&#xff1a; 创建一个test_http_dtw.py并运行 from flask import Flask, request, jsonifyapp Flask(__name__)# 示例分析函数 def analysis(data):…

WLAN 技术指南:从入门到原理

文章目录 目录 文章目录 前言 一.WLAN 基本概念 有线侧组网概念 AP-AC 组网方式 AC 连接方式 CAPWAP 协议 无线侧组网概念 无线信道 ​编辑 BSS/SSID/BSSID ​编辑 VAP ESS 二.WLAN 组网架构 基本的 WLAN 组网架构 四.WLAN 工作原理 AP 上线 AP 获取 IP 地址阶段 CAP…

语言学习专用AI播放器推荐:LLPlayer

学语言&#xff0c;经常会看大量的比较优秀的视频材料&#xff0c;那么推荐一款语言学习利器&#xff0c;极大提高生产力。 LLPlayer 是一款专为语言学习者设计的独特视频播放器。 它具有许多重要功能&#xff0c;例如可同时显示文本字幕和位图字幕、使用 OpenAI Whisper 自动…

mysql 关联表查询,索引失效

来源表: ##示例 CREATE TABLE order_wide (order_id varchar(33) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 订单ID,member_id int(11) DEFAULT NULL COMMENT 用户ID,content varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 订单标签,PRIMARY KEY (order_…

Oracle DG库手动注册归档日志的两种方法

Oracle DG库手动注册归档日志的两种方法 注册单个归档日志文件注册多个归档日志文件有的时候由于网络或各种原因,Oracle DG库服务器上可能缺少部分归档日志文件,导致DG库的MRP进程一直处于WAIT_FOR_GAP状态。 此时我们可以手动从主库或其他DG拷贝归档日志到当前DG服务器,并…

中小型VUE3项目创建流程相关命令tips

开新项目因为距离上次初始化时间太过久远,忘记初始化命令的有多少? 不得已简要记录一下流程 1. 使用vite构建新项目 1.1 构建 npm create vite@latest my-vue-app --template vue1.2 安装依赖 npm install1.3 启动 npm run dev参考文档 2. 添加需要的插件 2.1 准备工作…

Web后端开发(请求、响应)

目录 请求&#xff1a; Postman&#xff1a; 简单参数&#xff1a; 实体参数&#xff1a; 数组集合参数&#xff1a; 日期参数&#xff1a; Json参数&#xff1a; 路径参数&#xff1a; 响应&#xff1a; 请求响应&#xff1a; 请求&#xff1a;获取请求数据 响应&a…

Excel大厂自动化报表实战(互联网金融-数据分析周报制作上)

这是Excel大厂自动化报表实战第二期--互联网金融-数据分析周报制作上 数据资源已经与这篇博客捆绑&#xff0c;有需要者可以下载通过网盘分享的文件&#xff1a;2.4自动化报表-8月成交数据.xlsx&#xff0c;2.4自动化报表-8月获客数据.csv等2个文件 链接: https://pan.baidu.co…

HTTP 网络协议演进过程

网络协议演进问题&#xff0c;涉及到HTTP版本之间的连接复用优化和协议升级&#xff08;特别是从HTTP/2到HTTP/3&#xff09;的核心变化。我们以 HTTP/1.0 到 HTTP/2.0&#xff0c;再到 HTTP/3.0 的演进顺序来详细解释它们在通道复用&#xff08;TCP/QUIC&#xff09;上的优化和…

Xsens动捕和Manus数据手套在元宇宙数字人制作中提供解决方案

硬件连接与数据传输 Xsens与Manus集成&#xff1a;Xsens惯性动作捕捉系统负责捕捉人体的身体动作&#xff0c;Manus数据手套专门精确捕捉手指动作。Xsens动捕套装上有接口或无线连接模块&#xff0c;可与Manus手套配对和传输数据&#xff0c;将身体与手指跟踪数据结合。 Face…

【Java开发日记】简单说一说使用 Netty 进行 Socket 编程

目录 什么是 Netty 对比Netty和传统的Socket 传统Socket编程服务端 传统Socket编程客户端 Netty环境搭建 先创建出来一个项目 Netty服务端程序 Netty客户端程序 Channel Channel分类 为什么选择Netty 什么是 Netty Netty是由JBOSS提供的一个java开源框架&#xff0c…

目标检测任务的评估指标mAP50和mAP50-95

mAP50 和 mAP50-95 是目标检测任务中常用的评估指标&#xff0c;用于衡量模型在不同 交并比&#xff08;IoU&#xff09;阈值 下的平均精度&#xff08;Average Precision, AP&#xff09;。它们的区别主要体现在 IoU 阈值范围 上。 ✅ 1. mAP50&#xff08;mean Average Prec…

COHERENT XPRV23光电接收器控制软件

COHERENT XPRV23光电接收器控制软件

执行应用共享内存空间 同步QT进行快速捕获数据流

引言&#xff1a;本文章针对驱动的应用app&#xff0c;例如sensor data内容的获取&#xff0c;显示到QT的一种办法&#xff0c;共享内存。举例子&#xff0c;这是一个常见需求&#xff0c;比如摄像头采集进程与 GUI 显示进程分离&#xff0c;通过共享内存传输图像&#xff0c;避…

opencl的简单介绍以及c++实例

&#x1f9e9; 一、什么是 OpenCL&#xff1f; OpenCL&#xff08;Open Computing Language&#xff09; 是一个用于异构计算的开放标准&#xff0c;由 Khronos Group 提出和维护。它允许你在各种计算设备上&#xff08;如 CPU、GPU、DSP、FPGA&#xff09;并行运行代码&#…

ThingsCloud事物云平台搭建-微信小程序

ThingsCloud云平台与微信小程序设计 本文主要是介绍ThingsCloud云平台的搭建及微信小程序与app的使用。 当前文章是作为一个通用案例,介绍如何快速使用 ThingsCloud云平台 以及 利用 ThingsCloud云平台平台的框架快速设计手机APP和微信小程序。 可以快速让硬件接入,实现硬件…

2024 一带一路暨金砖国家职业技能大赛(金砖国家未来技能和技术挑战赛)

2024 一带一路暨金砖国家职业技能大赛&#xff08;金砖国家未来技能和技术挑战赛任务书&#xff09; 1 参加比赛的形式&#xff1a;2 项目阶段简介&#xff1a;3 项目阶段和所需时间&#xff1a;4 第一阶段&#xff1a;职业素养与理论技能4.1 项目 1.职业素养4.2 项目 2.法律法…

2025-06-13【api】阿里百炼api调用方法

通过调用各种大模型可以完成对文生文&#xff0c;文生图&#xff0c;图片理解&#xff0c;文生视频&#xff0c;音频识别&#xff0c;文转音频等需求。 #方法一 import os from openai import OpenAI# 初始化客户端 client OpenAI(api_keyos.getenv("DASHSCOPE_API_KEY&…

软件工程的软件生命周期通常分为以下主要阶段

软件工程的软件生命周期通常分为以下主要阶段&#xff1a; 可行性分析 &#xff1a;评估项目的技术、经济、操作和法律可行性&#xff0c;确定项目是否值得开发。需求分析 &#xff1a;明确用户需求&#xff0c;定义软件功能和非功能需求&#xff0c;形成需求规格说明书。系统…

Spring依赖注入的四种方式(面)

目录 1. 构造器注入 2. 字段注入 3. Setter注入 4. 方法注入 最佳实践建议 1. 构造器注入 Service public class UserService {private final UserRepository userRepository;Autowired // Spring 4.3 可以省略public UserService(UserRepository userRepository) {this.…