概要
OAuthのPKCEを実装したAPIなどを呼び出す際に必要になる code_challenge
の生成方法のTips
具体的には
[ここ] (https://tools.ietf.org/html/rfc7636#section-4.2) の 4.2. Client Creates the Code Challenge
に記載のある以下の code_challenge
をAndroid標準機能を使って作る方法
S256
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
やり方
以下の "codeChallenge" でString型のcode_verifier
をcode_challenge
に変換可能。
import android.util.Base64
import java.security.MessageDigest
val String.codeChallenge: String
get() {
val digest = MessageDigest.getInstance("SHA-256")
val bytes = digest.digest(toByteArray())
// **重要** encodeToStringの第2引数のフラグをちゃんと指定する
return Base64.encodeToString(bytes, Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING)
}
ロジックが正しいことの検証方法
[ここ] (https://tools.ietf.org/html/rfc7636#appendix-B) に code_challenge_method
がS256
のケースにおける
正しいcode_verifier
とcode_challenge
の組み合わせが記載されている。
code_verifier
がdBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
の場合 code_challenge
はE9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
が正解とのこと。
はまりどころ
Base64.encodeToStringのパラメータをちゃんと指定することが重要。
引数指定がない場合、
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
は
E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw+cM=\n
になる。
このため、以下の3つのパラメータが必要。
-
URL_SAFE
+
,-
,/
を適切に変換してURLセーフにする -
NO_WRAP
最後の改行コードを消す -
NO_PADDING
改行コードの前の=
を消す
この記事書いた理由
このAPIをAndroidで呼ぶ際にハマって時間無駄にしたため。