도구스개발

OAuth PKCE 코드 생성기

RFC 7636의 code_verifier를 난수로 만들고 S256 방식의 code_challenge를 계산합니다. base64url에서 패딩을 떼고 +/를 -_로 바꾸는 규칙까지 그대로 지킨 값이 나옵니다.

code_challenge (S256)

E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

BASE64URL(SHA256(ASCII(code_verifier))) · 43자

code_verifier — 토큰 요청에 넣습니다

dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

code_challenge — 인가 요청에 넣습니다

E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

code_challenge_method

S256

verifier 길이43자 (43~128 허용)
문자 집합unreserved만 사용
길이로 본 엔트로피 상한258비트
RFC 7636 §4.1만족
지금 값은 RFC 7636 부록 B의 예시입니다. 문서에 그대로 실려 있는 공개된 값이라 실제 인증에는 쓸 수 없습니다. 위의 «난수로 새로 만들기»를 눌러 주세요.
계산 근거 — RFC 7636 §4.1·§4.2code-verifier = 43*128unreservedunreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))최소 길이 43자는 우연이 아닙니다. §7.1이 256비트 이상의 엔트로피를 권고하는데, 32바이트를 base64url로 적으면 정확히 43자가 됩니다. 이 계산기도 32바이트를 난수로 뽑아 base64url하는 표준적인 방식으로 만듭니다.
base64url에 함정이 몰려 있습니다. 보통의 base64와 세 가지가 다릅니다 — +-로, /_로 바꾸고, 끝의 패딩 =뗍니다. 셋 중 하나만 빠뜨려도 인가 서버가 challenge 불일치로 거절합니다. 특히 패딩은 라이브러리가 알아서 붙여 버리는 일이 잦아 «코드는 맞는데 invalid_grant가 난다»의 단골 원인입니다.
plain은 쓰지 마세요. code_verifier를 그대로 보내는 방식이라 인가 요청을 엿본 쪽이 그 값을 그대로 재사용할 수 있고, PKCE를 붙인 의미가 사라집니다. RFC 7636도 S256을 계산할 수 있으면 반드시 S256을 쓰라고 정하고 있으며, plain은 SHA-256을 쓸 수 없는 제한된 환경을 위한 예외입니다. 여기서는 비교해 볼 수 있도록 남겨 두었습니다.
이 페이지에서 만든 값을 실제 인증에 쓰지 마세요. 난수는 브라우저의 crypto.getRandomValues, 해시는 crypto.subtle.digest로 계산하므로 값이 서버로 전송되지는 않습니다. 다만 화면에 띄운 이상 어깨 너머로 보일 수 있고, 실제 PKCE는 클라이언트가 인가 요청마다 새로 만들어 그 세션에서만 써야 하는 값입니다. 이 도구는 구현이 맞았는지 대조해 보는 용도입니다.

사용 방법

  1. 1code_challenge_method를 고릅니다. 특별한 사정이 없으면 S256입니다.
  2. 2code_verifier의 길이를 고릅니다. 32바이트(43자)가 RFC의 권고값입니다.
  3. 3«난수로 새로 만들기»를 누르면 브라우저 안에서 새 code_verifier가 만들어지고 code_challenge가 함께 계산됩니다.
  4. 4code_challenge와 code_challenge_method는 인가 요청에, code_verifier는 토큰 요청에 넣습니다.
  5. 5이미 있는 code_verifier를 붙여 넣어 규격을 만족하는지, challenge가 맞게 나오는지 대조해 볼 수도 있습니다.

자주 묻는 질문

인가 코드 가로채기 공격을 막습니다. 모바일 앱이나 SPA 같은 공개 클라이언트는 클라이언트 시크릿을 숨길 수 없어서, 인가 코드를 가로챈 공격자가 그것을 토큰으로 바꾸는 것을 막을 수단이 없었습니다. PKCE는 매 요청마다 새 비밀(code_verifier)을 만들고 그 해시만 먼저 보내므로, 코드를 훔쳐도 원본 비밀을 모르면 토큰을 받을 수 없습니다.

S256 방식이면 code_challenge = BASE64URL(SHA256(ASCII(code_verifier)))입니다. code_verifier를 ASCII로 읽어 SHA-256 해시를 낸 뒤, 그 32바이트를 패딩 없는 base64url로 적습니다. 결과는 항상 43자입니다. plain 방식이면 code_verifier를 그대로 씁니다.

RFC 7636 §4.1에 따라 43자 이상 128자 이하이며, unreserved 문자(A~Z, a~z, 0~9, -, ., _, ~)만 쓸 수 있습니다. 최소 43자라는 값은 §7.1이 권고하는 256비트 엔트로피와 맞물려 있습니다. 32바이트 난수를 base64url로 적으면 정확히 43자가 되기 때문입니다.

세 가지가 다릅니다. +를 -로, /를 _로 바꾸고, 끝의 패딩 =를 뗍니다. 셋 중 하나만 빠뜨려도 인가 서버가 challenge 불일치로 거절합니다. 특히 패딩은 라이브러리가 알아서 붙여 버리는 일이 잦아, 코드는 맞는데 invalid_grant가 나는 흔한 원인입니다.

권장되지 않습니다. plain은 code_verifier를 그대로 보내는 방식이라, 인가 요청을 엿본 쪽이 그 값을 그대로 재사용할 수 있어 PKCE를 붙인 의미가 사라집니다. RFC 7636도 S256을 계산할 수 있는 클라이언트는 반드시 S256을 쓰도록 정하고 있으며, plain은 SHA-256을 쓸 수 없는 제한된 환경을 위한 예외입니다.

쓰지 않는 것이 좋습니다. 화면에 띄운 값은 어깨 너머로 보일 수 있고, 실제 PKCE의 code_verifier는 클라이언트가 인가 요청마다 새로 만들어 그 세션에서만 쓰고 버려야 하는 값입니다. 이 도구는 직접 구현한 코드가 맞는 값을 내는지 대조해 보는 용도로 만들어졌습니다.

전송되지 않습니다. 난수는 브라우저의 crypto.getRandomValues, 해시는 crypto.subtle.digest로 계산하며 모두 이 페이지 안에서 끝납니다. 붙여 넣은 code_verifier도 네트워크로 나가지 않습니다.

RFC 7636 부록 B의 예시 쌍으로 대조합니다. code_verifier가 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk이면 S256 code_challenge는 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM입니다. 화면의 «RFC 예시 넣기»를 누르면 이 쌍이 그대로 나오는지 확인할 수 있습니다.

알아두면 좋은 점

  • RFC 7636 부록 B의 예시 쌍(verifier·challenge)을 테스트에 박아 두었고, SHA-256은 FIPS 180-4의 예시 값으로 함께 검증했습니다.
  • 이 페이지에서 만든 값은 대조·학습용입니다. 실제 인증에는 클라이언트가 요청마다 새로 만든 값을 쓰세요.
  • plain 방식은 비교용으로만 남겨 두었습니다. 실제로는 S256을 쓰세요.
  • 난수는 브라우저의 WebCrypto를 그대로 씁니다. 오래된 브라우저에서 crypto.getRandomValues나 crypto.subtle을 지원하지 않으면 값이 생성되지 않습니다.
  • 입력한 값은 브라우저 안에서만 계산되며 서버로 전송되지 않습니다.

함께 보면 좋은 도구

마지막 검증: 2026년 8월 31일 · 결과는 참고용 추정치입니다.