bibimbap/.serena/memories/bibimbap-auth-pbkdf2-not-bc...

1.9 KiB

bibimbap 인증: 자체 PBKDF2 해시 (BCrypt 아님)

Spring Security 미사용. 로그인은 UserController 자체 구현 password 검증.

password_hash 포맷: pbkdf2_sha256$<iter>$<base64(salt)>$<base64(hash)> ($ 4필드)

  • 알고리즘 PBKDF2WithHmacSHA256, iterations=210000, keyLength=256bit(=32byte), salt=16byte SecureRandom
  • base64 = 표준(padding 포함). 검증: UserController.verifyPassword (src/main/java/com/pandoli365/bibimbap/controller/api/UserController.java:46-48, 550-584). parts[0]=="pbkdf2_sha256" && len==4 확인 → 동일 iter/salt 재계산 → MessageDigest.isEqual 상수시간 비교.

함정 (Why save)

외부 BCrypt 생성기로 만든 해시는 무효 — 형식 자체가 다름. 코드 안 보면 "BCrypt 일 것"이라는 기본 가정이 강해, 로그인 가능 더미/테스트/관리자 계정 seed 마다 반복적으로 부딪힌다.

로그인 가능 계정 seed 시 필수 조건

  • users.status = 'ACTIVE' (UserController.java:148-149, 미충족 시 로그인 거부)
  • user_auth_identities.provider = 'email' (단일 provider, UserController.java:42)
  • provider_user_id = 정규화(trim + lowercase) 이메일 (UserController.java:527-533)
  • 양쪽 is_delete = false
  • 세션 귀속 키: 로그인 성공 시 session attribute userId(Long) 저장 → 리뷰/댓글 작성 가드가 이 키를 읽음.

평문→해시 생성 (Python, Java 와 byte-identical)

import hashlib, base64, os
salt = os.urandom(16)
dk = hashlib.pbkdf2_hmac('sha256', pw.encode(), salt, 210000, dklen=32)
h = f"pbkdf2_sha256$210000${base64.b64encode(salt).decode()}${base64.b64encode(dk).decode()}"

로그인 동작 보장은 실제 verifyPassword 코드 경로로 positive/negative 둘 다 확인할 것 (호스트 JDK 없으면 mem:java-crypto-verify-via-jdk-container-when-no-host-jdk 참조).

근거 세션: .atp/work-session/20260618-121419 (더미 seed). 관련 산출물 db/seed-dev.sql.