OAuth PKCE 코드 생성기
RFC 7636의 code_verifier를 난수로 만들고 S256 방식의 code_challenge를 계산합니다. base64url에서 패딩을 떼고 +/를 -_로 바꾸는 규칙까지 그대로 지킨 값이 나옵니다.
code_challenge (S256)
E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
BASE64URL(SHA256(ASCII(code_verifier))) · 43자
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
S256
+를 -로, /를 _로 바꾸고, 끝의 패딩 =를 뗍니다. 셋 중 하나만 빠뜨려도 인가 서버가 challenge 불일치로 거절합니다. 특히 패딩은 라이브러리가 알아서 붙여 버리는 일이 잦아 «코드는 맞는데 invalid_grant가 난다»의 단골 원인입니다.crypto.getRandomValues, 해시는 crypto.subtle.digest로 계산하므로 값이 서버로 전송되지는 않습니다. 다만 화면에 띄운 이상 어깨 너머로 보일 수 있고, 실제 PKCE는 클라이언트가 인가 요청마다 새로 만들어 그 세션에서만 써야 하는 값입니다. 이 도구는 구현이 맞았는지 대조해 보는 용도입니다.사용 방법
- 1code_challenge_method를 고릅니다. 특별한 사정이 없으면 S256입니다.
- 2code_verifier의 길이를 고릅니다. 32바이트(43자)가 RFC의 권고값입니다.
- 3«난수로 새로 만들기»를 누르면 브라우저 안에서 새 code_verifier가 만들어지고 code_challenge가 함께 계산됩니다.
- 4code_challenge와 code_challenge_method는 인가 요청에, code_verifier는 토큰 요청에 넣습니다.
- 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일 · 결과는 참고용 추정치입니다.