OAuth2.1的code_challenge和code_vertifier理解
以下来自人工自能的回答。
OAuth 2.0 提供了多种授权模式,其中授权码模式(Authorization Code Grant)是最常用和最安全的一种。而 code_challenge 是该模式中的一个安全增强特性,主要用于 PKCE(Proof Key for Code Exchange)机制。
什么是 PKCE?
PKCE(Proof Key for Code Exchange)是一种扩展,旨在提高 OAuth 2.0 授权码模式的安全性,特别是当授权码在公共客户端(如运行在浏览器中的 JavaScript 应用或移动应用)中使用时。PKCE 通过在授权请求中添加一个额外的验证步骤来防止授权码被拦截和滥用。
code_challenge 的作用
code_challenge 是 PKCE 机制的一部分,它在授权请求阶段生成并发送。它基于一个秘密值(称为 code_verifier),通过一种散列算法(如 S256)进行变换得到。code_challenge 的目的是在不直接暴露 code_verifier 的情况下,为后续的令牌请求提供一个验证基础。
code_challenge 和 code_verifier 的生成与使用
-
生成
code_verifier:code_verifier是一个高熵、随机生成的字符串,通常至少为 128 位(即 16 字节)长,并且建议使用字母数字字符以及-._~+/字符集中的字符。 -
生成
code_challenge:
使用code_verifier,通过一种散列算法(如 S256)生成code_challenge。对于 S256,code_challenge是code_verifier的 SHA-256 哈希值的 Base64 URL 编码,但要去掉编码中的=填充字符,并且确保输出的长度是 43 个字符(由于 Base64 URL 编码后每 4 个字符代表 3 个字节,但最后一个字符块可能不足 4 个字符,所以去掉=后长度可能略有变化)。 -
在授权请求中使用
code_challenge:
在发起授权请求时,将code_challenge作为请求参数之一发送给授权服务器。 -
在令牌请求中使用
code_verifier:
当授权服务器返回授权码后,客户端使用这个授权码以及之前生成的code_verifier向令牌端点请求访问令牌。授权服务器将验证code_challenge和code_verifier是否匹配,从而确保请求是由原始客户端发起的。
示例
假设 code_verifier 是 dBjftJeZ4CVP-mB92K27uhbUX6vhSWQ,那么对应的 code_challenge(使用 S256)将是 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstxsMPk。
个人理解:
1. code_verifier是随机生成的字符串,基于这个字符串使用散列算法(S256)生成code_challenge。通过code_challenge是很难猜测计算得到code_verifier的。下面是授权码模式的认证流程。

code_chanllenge和code_verifier是网站W生成的,在第2步发送给浏览器的重定向url中设定code_challenge。例如:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&code_challenge=6fdkQaPm51l13DSukcAH3Mdx7_ntecHYd1vi3n0hMZY&code_challenge_method=S256 HTTP/1.1
Host: server.example.com
2. 在第8步之前,认证服务器生成授权码,会记录下code_challenge和授权码的成对关系。
3. 在第10步,当网站W拿着授权码去认证中心获取Token时,会把code_verifier带上。例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencodedgrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
&code_verifier=3641a2d12d66101249cdf7a79c000c1f8c05d2aafcf14bf146497bed
总结:
这一套机制是为了确保拿着授权码来获取token的客户端,是当时当时认证服务器把授权码颁发给的对象。
