LoginSignup
6
2

More than 3 years have passed since last update.

PKCEにおけるcode_challenge生成について

Last updated at Posted at 2020-07-25

概要

OAuth2.0の文脈にて、パブリッククライアントが構成要素に含まれる場合にはよくお世話になるPKCE(Proof Key for Code Exchange)のcode_challengeの生成について記述します。

また、ここではcode_challenge_methodS256の時のことのみを考えます。

OAuth2.0の話や、PKCEの効用などは述べません。

code_challenge生成方法

RFC7636によると、code_challengeの生成方法は以下のように定義されています。

      code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

RFCにて、code_challenge_methodS256の時の具体例として、
code_verifierdBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXkのときには、
code_challengeE9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cMになる
とあるので、この例について説明していきます。

code_verifierをSHA256でハッシュ値にする

前提としてcode_verifierアルファベット数字-._~からなり、43~128文字から成ります。

   ABNF for "code_verifier" is as follows.

   code-verifier = 43*128unreserved
   unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
   ALPHA = %x41-5A / %x61-7A
   DIGIT = %x30-39

code_verifierのハッシュ値変換は、定義におけるSHA256(ASCII(code_verifier))の部分で実施しています。
これをgit-bash上で実施すると以下のようになります。

$ echo -n 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk' | shasum -a 256
13d31e961a1ad8ec2f16b10c4c982e0876a878ad6df144566ee1894acb70f9c3 *-

13D31E961A1AD8EC2F16B10C4C982E0876A878AD6DF144566EE1894ACB70F9C3というハッシュ値が得られたことがわかります。

得られたハッシュ値をBASE64エンコードする

上記で得られたハッシュ値をBASE64エンコードするのですが、この値は16進数で表記されたものとして扱わなければいけません。
つまり、以下コマンドのように上記ハッシュ値を文字列としてBASE64エンコードしても、望む値は得られません。

$ echo -n '13D31E961A1AD8EC2F16B10C4C982E0876A878AD6DF144566EE1894ACB70F9C3' | base64
MTNEMzFFOTYxQTFBRDhFQzJGMTZCMTBDNEM5ODJFMDg3NkE4NzhBRDZERjE0NDU2NkVFMTg5NEFD
QjcwRjlDMw==

代わりに、xxdコマンドを使って値を16進数表記された文字列としてみると、期待する結果に近い値が取得できます。(下記、WSLで実行。git-bashにxxdコマンドがないため)

nannany@MyComputer:/mnt/c/WINDOWS/system32$ echo "13D31E961A1AD8EC2F16B10C4C982E0876A878AD6DF144566EE1894ACB70F9C3" | xxd -r -p | base64
E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw+cM=

得られたE9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw+cM=をURLとして使える値にするために、

  • パディングの=を削除
  • +-に変換
  • /_に変換

します。

その結果、期待したcode_challengeを取得することができます。

nannany@MyComputer:/mnt/c/WINDOWS/system32$ echo "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw+cM=" | sed -e 's/=//g' | sed -e 's/+/-/g' | sed -e 's/\//_/g' | xargs -I {} test "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM" == {} ; echo $?
0

雑感

得られたハッシュ値を文字列として扱ってはまりました。

参考

code_challengeの生成方法
code_challenge_methodがS256の時の具体例

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2