OAuth 2.0 扩展协议之 PKCE( 三 )

// Required: Node.js crypto module// https://nodejs.org/api/crypto.html#crypto_cryptofunctionsha256( buffer) { returncrypto.createHash( 'sha256').update(buffer).digest; }varchallenge = base64URLEncode...

// Required: Node.js crypto module// https://nodejs.org/api/crypto.html#crypto_cryptofunctionsha256( buffer) { returncrypto.createHash( 'sha256').update(buffer).digest; }varchallenge = base64URLEncode(sha256(verifier)); java 示例
// Dependency: Apache Commons Codec// https://commons.apache.org/proper/commons-codec/// Import the Base64 class.// import org.apache.commons.codec.binary.Base64;byte[] bytes = verifier.getBytes( "US-ASCII"); MessageDigest md = MessageDigest.getInstance( "SHA-256"); md.update(bytes ,0 ,bytes.length); byte[] digest = md.digest; String challenge = Base64.encodeBase64URLSafeString(digest);C# 示例
publicstaticstringbase64urlencodeNoPadding( byte[] buffer ) {stringbase64 = Convert.ToBase64String(buffer); base64 = base64.Replace( "+" ,"-"); base64 = base64.Replace( "/" ,"_"); base64 = base64.Replace( "=" ,""); returnbase64; }stringcode_challenge = base64urlencodeNoPadding(sha256(code_verifier));
原理分析
上面我们说了授权码拦截攻击 , 它是指在整个授权流程中 , 只需要拦截到从授权服务器回调给客户端的授权码code , 就可以去授权服务器申请令牌了 , 因为客户端是公开的 , 就算有密钥client_secret也是形同虚设 , 恶意程序拿到访问令牌后 , 就可以光明正大的请求资源服务器了 。
PKCE是怎么做的呢? 既然固定的client_secret是不安全的 , 那就每次请求生成一个随机的密钥(code_verifier) , 第一次请求到授权服务器的authorize endpoint时 ,携带code_challenge 和 code_challenge_method , 也就是code_verifier转换后的值和转换方法 , 然后授权服务器需要把这两个参数缓存起来 , 第二次请求到token endpoint时 , 携带生成的随机密钥的原始值 (code_verifier), 然后授权服务器使用下面的方法进行验证:
  • plain
code_challenge = code_verifier
  • S256 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
通过后才颁发令牌 , 那向授权服务器authorize endpoint和token endpoint发起的这两次请求 , 该如何关联起来呢? 通过授权码code即可 , 所以就算恶意程序拦截到了授权码code , 但是没有code_verifier , 也是不能获取访问令牌的 , 当然PKCE也可以用在机密(confidential)的客户端 , 那就是client_secret + code_verifier双重密钥了 。
最后看一下请求参数的示例:
GET /oauth2/authorize https://www.authorization-server.com/oauth2/authorize?response_type=code&client_id=s6BhdRkqt3&scope=user&state=8b815ab1d177f5c8e &redirect_uri=https://www.client.com/callback&code_challenge_method=S256 &code_challenge=FWOeBX6Qw_krhUE2M0lOIH3jcxaZzfs5J4jtai5hOX4
POST /oauth2/token Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencodedhttps://www.authorization-server.com/oauth2/token?grant_type=authorization_code&code=d8c2afe6ecca004eb4bd7024&redirect_uri=https://www.client.com/callback&code_verifier=2D9RWc5iTdtejle7GTMzQ9Mg15InNmqk3GZL-Hg5Iz0
下边使用Postman演示了使用PKCE模式的授权过程 。
OAuth 2.0 扩展协议之 PKCE
文章图片

参考文献
  • https://www.rfc-editor.org/rfc/rfc6749
  • https://www.rfc-editor.org/rfc/rfc7636.html
  • https://oauth.net/2/pkce
  • https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-04
微软最有 价值专家(MVP)
微软最有价值专家是微软公司授予第三方技术专业人士的一个全球奖项 。 28年来 , 世界各地的技术社区领导者 , 因其在线上和线下的技术社区中分享专业知识和经验而获得此奖项 。

特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。