代码交换证明密钥(Proof Key for Code Exchange,简称PKCE)

代码交换证明密钥(Proof Key for Code Exchange,简称PKCE)是一种用于增强OAuth 2.0授权码流程安全性的扩展机制。PKCE主要用于公共客户端(如原生应用和单页应用),这些客户端无法安全地存储客户端密钥(Client Secret)。PKCE通过引入一个额外的“证明密钥”来防止授权码被拦截和滥用。

PKCE的工作原理

  1. 生成Code Verifier: 客户端生成一个随机的、足够长的字符串,称为code_verifier。这个字符串是唯一的,并且只在当前授权请求中使用。

  2. 生成Code Challenge: 客户端对code_verifier进行哈希处理(通常使用SHA-256算法),并将结果进行Base64 URL编码,得到code_challenge

  3. 发起授权请求: 客户端将code_challengecode_challenge_method(例如“S256”表示使用SHA-256算法)一起发送到授权服务器的授权端点(/authorize)。

  4. 用户认证和授权: 用户在授权服务器上进行认证并授权,授权服务器生成授权码并将其返回给客户端。

  5. 交换授权码: 客户端将授权码和之前生成的code_verifier一起发送到授权服务器的令牌端点(/token)。

  6. 验证Code Verifier: 授权服务器使用收到的code_verifier和之前存储的code_challenge进行验证。如果验证通过,授权服务器返回访问令牌和刷新令牌。

PKCE的安全性

PKCE通过引入code_verifiercode_challenge,确保只有发起授权请求的客户端才能成功交换授权码。这有效地防止了授权码拦截攻击,因为即使攻击者截获了授权码,也无法在没有code_verifier的情况下成功交换令牌。

示例代码

以下是一个使用PKCE的伪代码示例:

import hashlib
import base64
import os

# 生成code_verifier
code_verifier = base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip('=')

# 生成code_challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').rstrip('=')

# 发起授权请求
authorization_url = f"https://authorization-server.com/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&code_challenge={code_challenge}&code_challenge_method=S256"
print("请访问以下URL进行授权:", authorization_url)

# 用户完成授权后,使用code_verifier交换授权码
authorization_code = input("请输入授权码: ")
token_response = requests.post("https://authorization-server.com/token", data={
    'grant_type': 'authorization_code',
    'code': authorization_code,
    'redirect_uri': 'YOUR_REDIRECT_URI',
    'client_id': 'YOUR_CLIENT_ID',
    'code_verifier': code_verifier
})

print("访问令牌:", token_response.json().get('access_token'))

参考资料

最后更新于