これは何?
OAuth2.0では,PKCE(Proof Key for Code Exchange by OAuth Public Clients)を使って認可コード横取り攻撃を防止できます。このときクライアント(例:スマホ)と認可サーバでは,それぞれで検証コード(code_verifier)からチャレンジコード(code_challenge)を算出します(詳しい話は参考リンクをご参照ください)。この算出方法をPythonで試してみました。
確認したこと
RFC7636にサンプル記載があるように,
code_verifier:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
から
code_challenge:E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
を算出できることを確認します。
ロジックはRFC7636 4.2. Client Creates the Code Challenge に示されています。検証コードをSHA-256でハッシュした値を,base64urlでエンコードします。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
この方式をs256と呼びます。
テスト用のコードと実行結果
import base64, hashlib
code = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
print('code_verifier:{}'.format(code))
sha256hash = hashlib.sha256(code.encode()).digest()
print('sha256 hash:{}'.format(sha256hash))
challenge = base64.urlsafe_b64encode(sha256hash).rstrip(b'=').decode()
print('base64url encode:{}'.format(challenge))
実行結果はこちら
$ python3 pkce.py
code_verifier:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
sha256 hash:b'\x13\xd3\x1e\x96\x1a\x1a\xd8\xec/\x16\xb1\x0cL\x98.\x08v\xa8x\xadm\xf1DVn\xe1\x89J\xcbp\xf9\xc3'
base64url encode:E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
RFC7636 Appendix Bの結果と一致しました。
参考リンク
RFC7636
https://www.authlete.com/ja/developers/pkce/
https://dev.classmethod.jp/articles/oauth-2-0-pkce-by-auth0/
https://developers.line.biz/ja/docs/line-login/integrate-pkce/#how-to-integrate-pkce