Skip to content

perf(auth): OIDC 토큰 지연 해소 — client_secret SHA-256 + 비밀번호 네이티브 scrypt 전환 - #73

Merged
mack-erel merged 1 commit into
mainfrom
perf/oidc-token-scrypt-sha256
Jul 2, 2026
Merged

perf(auth): OIDC 토큰 지연 해소 — client_secret SHA-256 + 비밀번호 네이티브 scrypt 전환#73
mack-erel merged 1 commit into
mainfrom
perf/oidc-token-scrypt-sha256

Conversation

@mack-erel

Copy link
Copy Markdown
Owner

문제

RP(drone.devday.one)의 OIDC 콜백이 약 6초 걸립니다. 콜백 처리 중 RP 가 KeyStone 의 POST /oidc/token 을 호출하는데, 이 엔드포인트가 요청마다 client_secret 을 @hicaru/argon2-pure.js(순수 JS argon2id, m=7168/t=5)로 검증하면서 verify 1회에 ~4.4초의 CPU 를 태우는 것이 주범이었습니다 (로컬 실측 4,372ms). 로그인의 비밀번호 검증도 같은 코드 경로라 동일하게 느렸습니다.

해결

1. client_secret 검증: argon2 → SHA-256 (src/lib/server/oidc/client.ts)

client_secret 은 서버가 생성한 32바이트 랜덤값(256비트 엔트로피) 이라 사전공격·무차별대입이 불가능하므로, 저엔트로피 비밀번호용 메모리 하드 KDF 대신 SHA-256 단일 해시(sha256$<b64u>)로 충분합니다. 검증 4.4초 → <1ms.

  • 레거시 argon2/pbkdf2 해시는 기존 경로로 계속 검증되고, 성공 시 sha256 으로 자동 업그레이드 (토큰 엔드포인트에서 영속화, 실패 시 로깅)
  • public client(auth_method=none) 처리 등 기존 보안 검사는 그대로 유지

2. 비밀번호 해싱: 순수 JS argon2id → 네이티브 scrypt (src/lib/server/auth/password.ts)

Workers 는 런타임 WASM 바이트 컴파일을 금지해 WASM argon2 도입에는 빌드 배관이 필요한 반면, node:crypto scrypt 는 2025-04 부터 Workers 네이티브(BoringSSL) 지원됩니다 (better-auth 도 같은 이유로 채택).

  • 파라미터 N=32768, r=8, p=3 (32MiB) — OWASP 권고 조합, 기존 argon2(m=7168KB)보다 메모리 하드니스 상향
  • 신규 형식: scrypt$N=32768,r=8,p=3$<salt_b64>$<hash_b64>
  • 레거시 argon2id/pbkdf2 해시는 검증 성공 시 scrypt 로 자동 rehash (기존 authenticateLocalUser 영속화 경로 재사용) — 락아웃 없음
  • 향후 파라미터 상향 시에도 자동 재해싱
  • 저장 레코드의 N/r/p 파싱에 상한 검증 (조작된 레코드로 인한 메모리/CPU 증폭 방어)

3. /oidc/token 쿼리 병렬화

grant 소진 후 서로 독립인 조회 3개(유저·서명키·권한매핑)를 Promise.all 로 병렬화.

검증

  • 기능 테스트(bun): scrypt 왕복 118ms / 레거시 argon2·pbkdf2 검증 후 자동 업그레이드 / 오답 거부 / 조작 파라미터(N 과대, 비2제곱) 거부 — 통과
  • workerd 실제 런타임 스모크 테스트 (wrangler dev): scrypt 106ms, 결정적 동작 확인
  • svelte-check 0 에러, eslint/prettier 통과
  • 별도 보안 리뷰 패스: CRITICAL/HIGH 0건 (MEDIUM 지적 2건 반영: 파라미터 상향 rehash, 업그레이드 실패 로깅. scrypt 동시 실행 메모리 우려는 로그인 10회/15분·가입 5회/시간 레이트리밋으로 완화 확인)

배포 후 동작

  • 콜백 지연 6초 → 12초
  • 저장 해시가 argon2 인 기존 클라이언트는 배포 후 첫 토큰 교환 1회만 느린 경로를 타고 sha256 으로 업그레이드됨 (admin 에서 시크릿 재생성 시 이것도 생략 가능)
  • 기존 사용자의 첫 로그인도 1회만 레거시 검증 후 scrypt 전환

🤖 Generated with Claude Code

OIDC 콜백이 ~6초 걸리던 원인인 순수 JS argon2id(verify 1회 ~4.4초 CPU) 제거:

- client_secret 검증을 SHA-256 단일 해시(sha256$)로 전환. 서버 생성
  32바이트 랜덤값(256비트 엔트로피)이라 메모리 하드 KDF 불필요.
  레거시 argon2/pbkdf2 해시는 검증 성공 시 자동 업그레이드.
- 사용자 비밀번호 해싱을 node:crypto 네이티브 scrypt(N=32768,r=8,p=3,
  32MiB — OWASP 권고)로 전환. Workers 2025-04 부터 네이티브 지원,
  workerd 실측 106ms. 레거시 해시는 로그인 성공 시 자동 rehash,
  향후 파라미터 상향 시에도 자동 재해싱.
- /oidc/token 의 독립 조회 3개(유저/서명키/권한매핑) Promise.all 병렬화.

Co-Authored-By: Claude Fable 5 <[email protected]>
@mack-erel
mack-erel merged commit b13003c into main Jul 2, 2026
6 checks passed
@mack-erel
mack-erel deleted the perf/oidc-token-scrypt-sha256 branch July 2, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant