java 示例
// Required: Node.js crypto module // https://nodejs.org/api/crypto.html#crypto_crypto functionbase64URLEncode( str) {returnstr.toString( 'base64').replace( /\+/g ,'-').replace( /\//g ,'_').replace( /=/g ,'');} varverifier = base64URLEncode(crypto.randomBytes( 32));java 示例
// Required: Apache Commons Codec // https://commons.apache.org/proper/commons-codec/ // Import the Base64 class. // import org.apache.commons.codec.binary.Base64; SecureRandom sr = newSecureRandom;byte[] code = newbyte[ 32];sr.nextBytes(code); String verifier = Base64.getUrlEncoder.withoutPadding.encodeToString(code); c# 示例
publicstaticstringrandomDataBase64url( intlength ){ RNGCryptoServiceProvider rng = newRNGCryptoServiceProvider;byte[] bytes = newbyte[length];rng.GetBytes(bytes); returnbase64urlencodeNoPadding(bytes);} publicstaticstringbase64urlencodeNoPadding( byte[] buffer ) {stringbase64 = Convert.ToBase64String(buffer); base64 = base64.Replace( "+" ,"-"); base64 = base64.Replace( "/" ,"_"); base64 = base64.Replace( "=" ,""); returnbase64; }
stringcode_verifier = randomDataBase64url( 32);
code_challenge_method
对code_verifier进行转换的方法 , 这个参数会传给授权服务器 , 并且授权服务器会记住这个参数 , 颁发令牌的时候进行对比 , code_challenge == code_challenge_method(code_verifier), 若一致则颁发令牌 。
code_challenge_method可以设置为plain(原始值)或者S256(sha256哈希) 。
code_challenge
使用code_challenge_method对code_verifier进行转换得到code_challenge , 可以使用下面的方式进行转换
- plain code_challenge = code_verifier
- S256 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
客户端应该首先考虑使用S256进行转换 , 如果不支持 , 才使用plain , 此时 code_challenge和code_verifier的值相等 。
【模式|OAuth 2.0 扩展协议之 PKCE】java 示例
// 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# 示例
推荐阅读