前言
你好啊,我是你的人类朋友!
今天主要介绍断言(Assertion)相关的知识。
先定个小目标:看完你将可以用自己的语言向别人解释:啥是断言?
正文
一、初印象
断言(Assertion)在信息安全领域中,是一种用于证明身份的数字凭证。
简单来说,断言是一个【包含身份声明信息的安全令牌】,用于向服务端证明客户端的合法身份。
它通常包含三要素:
- 身份标识(如:AppId)
- 验证凭证(如:加密的 Secret)
- 完整性证明(如:数字签名)
二、工作流程
断言的工作过程可以分为四个核心步骤:
【1】首先,客户端 向认证服务请求生成断言,提供:
- 身份标识(AppId)
- 密钥(AppSecret)
- 客户端公钥(PublicKey)
补充:AppSecret 是啥? 它由服务提供方(如微信开放平台等)在为你创建应用时分配,与你应用的唯一身份标识 AppId 配套使用。它的核心作用是证明"持有此 AppId 的应用确实是其声称的那个应用",是验证你身份合法性的最关键凭证,必须像保护密码一样严格存储,绝不能在前端代码或公开场合泄露!!
【2】接着,认证服务:
- 使用客户端公钥 对AppSecret 进行RSA 加密,生成【加密凭证】
⚠️!注意区分客户端公钥 (Public Key)和 AppKey / AppId,他们是不同的!
- 使用SHA256 算法 对AppId + AppSecret + PublicKey 的组合进行哈希计算,生成【数字签名】
【3】然后,认证服务 将加密凭证 和数字签名 返回给客户端
【4】最后,客户端 将断言【包含身份标识、加密凭证、数字签名】提交给目标服务进行身份验证:
✨ 补充知识:
断言 = 身份标识(客户端 AppId)+ 加密凭证(认证服务返回)+ 签名(认证服务返回)
你可以参考下面的图形来帮助理解!⬇️⬇️
text
【断言生成阶段】
客户端 → 认证服务
│
├ 请求参数:
│ AppId: "client_123" ← 客户端身份标识
│ AppSecret: "secret_abc" ← 客户端密钥
│ PublicKey: "-----BEGIN PUBLIC KEY-----..." ← 客户端公钥
│
└ 认证服务处理:
1. 加密敏感数据:
encryptedSecret = RSA_Encrypt(PublicKey, AppSecret)
← 用客户端公钥对AppSecret进行RSA加密
2. 生成签名:
signature = SHA256(AppId + AppSecret + PublicKey)
← 用SHA256对三要素组合进行哈希计算
3. 返回断言组件:
┌───────────────────┐
│ • 加密凭证: encryptedSecret │
│ • 数字签名: signature │
└───────────────────┘
【断言使用阶段】
客户端 → 目标服务
│
├ 提交断言数据:
│ • AppId: "client_123" ← 客户端身份标识
│ • AppSecretEncoded: encryptedSecret ← 认证服务返回的加密凭证
│ • Signature: signature ← 认证服务返回的数字签名
│
└ 目标服务验证:
1. 解密凭证:
decryptedSecret = RSA_Decrypt(PrivateKey, encryptedSecret)
← 用客户端私钥对加密凭证进行RSA解密
2. 重新计算签名:
expectedSig = SHA256(AppId + decryptedSecret + PublicKey)
← 用SHA256对三要素组合重新哈希计算
3. 比对签名:
expectedSig == received Signature ?
│
├─ ✅ 一致 → 认证成功 → 返回访问令牌
└─ ❌ 不一致 → 认证失败 → 返回错误信息
关键角色说明
- 客户端:提供认证三要素,组装和提交断言
- 认证服务:生成加密凭证和数字签名
- 目标服务:验证断言的有效性,颁发访问令牌
- 断言:包含身份标识 + 加密凭证 + 数字签名的完整认证数据包
三、关于断言
🤔🤔 疑问 1:所以断言总结来说是一种令牌?还是凭证?还是签名?还是其他的啥东西?
【✍️ 回答】可以这样来理解:
断言本质上是一种"身份证明凭证",其核心目的是为了"身份认证"。
展开说说:
-
它是一种凭证
- 断言的形态是一个包含多种验证要素的数据包,类似于现实世界中的身份证或工作证。
-
但它不是简单的凭证,而是"包含验证要素的"
- 简单的身份标识(如用户名)任何人都可以使用,无法证明使用者的合法性。
- 断言的核心在于包含了加密验证要素:加密的密钥、数字签名等。没有正确的【密钥】和【算法】,就无法构造出有效的断言。
-
它的作用是"身份认证"
- 目的就是证明身份:断言用于向服务端证明客户端是合法的、经过认证的实体。
- 技术实现多样:断言可以通过数字签名、加密技术等多种密码学手段来实现身份验证。
🤔🤔 疑问 2:你提到了签名,签名不就是用私钥实现的吗?那是不是断言只用于非对称加密?
【✍️ 回答】不是的,断言既可用于非对称加密场景,也可用于对称加密场景。
签名确实常用私钥实现(非对称加密),但断言中的"签名"也可以是基于 HMAC 的(对称加密)
关键区别在于:非对称方案使用公钥/私钥对,提供不可否认性;
而对称方案使用共享密钥,性能更好但无法防止接收方伪造。
断言的核心是封装身份声明,具体采用哪种密码学机制取决于实际的安全需求。
🤔🤔 疑问 3:也就是说,签名不是非对称加密专属的?对称加密中也有签名这个概念?
是的,签名不是非对称加密的专属概念。在对称加密领域,HMAC(基于哈希的消息认证码)就扮演了"签名"的角色,它使用共享密钥对消息生成认证码,用于验证消息的完整性和真实性。虽然它不提供非对称加密的数字签名所具有的不可否认性,但在确保"消息由拥有密钥的合法发送方发出且未被篡改"这一核心功能上,其作用和目的与"签名"是相似的。
可恶啊。我之前就是以为签名只能用在非对称加密中,没想到对称加密中也有签名这个概念。🙀🙀🙀😥😥😥
四、小总结
断言的核心作用是身份认证,它不同于仅用于身份识别的标识(如 UserID,长期有效),也不同于用于资源授权的访问令牌(短期有效)。
断言本身是一个封装了身份信息、加密凭证和签名验证的安全凭证,通常在认证过程中【一次性】使用,以确保身份验证的安全性和可靠性。
🤔 疑问:一次性使用??啥意思?
✍️ 回答:"一次性"指的是断言通常仅在一次完整的认证流程中被使用。一旦客户端凭借此断言向认证服务成功换取了访问令牌(Access Token),该断言便立即失效,不能被重复使用以再次申请令牌。这有效防止了认证凭证被拦截和重放攻击,极大地提升了安全性。
五、补充:断言与相关概念的区别
哈希值是对数据计算出的固定长度摘要,用于验证数据完整性。
数字签名是使用非对称加密技术对哈希值进行加密的结果,用于验证数据来源和完整性。
断言则是综合运用加密和签名技术构建的身份认证凭证,在验证身份的基础上确保传输安全。
最后
回到开头的问题:啥是断言?
断言(Assertion)是一种数字身份凭证,包含身份标识、加密验证信息和完整性签名,用于在身份认证过程中证明客户端的合法身份。
服务端通过验证断言的各个组成部分来确认客户端的真实性,验证通过后通常会产生访问令牌用于后续的 API 调用。
任何对断言内容的篡改或伪造都会导致认证失败。