권한관리(SFR-001): - getAuthorities() 구현(EgovUserAuthorityDAO), AuthorityInterceptor 역할별 URL 접근제어 (COMTNMENUCREATDTLS×COMTNMENUINFO×COMTNPROGRMLIST 메뉴권한 기반, 캐시/TTL, ROLE_ADMIN 바이패스) - 권한 신청·승인 워크플로 + AUTHOR_CHANGE_HISTORY 이력(3년 보관), 조회·다운로드 계정관리(SFR-002): 계정관리정책, 장기미사용(휴면) 확장(취급자 포함)·사전알림, 계정잠금 5회 인증체계(SFR-003): 로그인 통합 2단계 인증(SecondFactorInterceptor+SecondFactorController), OTP QR 등록(ZXing)·비밀키 DB 영속(OTP_DEVICE, AES-GCM), 세션재발급(고정공격 방지), 자동로그아웃 30분 접속기록(SFR-004): PERSONAL_DATA_ACCESS_LOG(월파티션), PersonalDataLogAspect 한정수집, SHA-256 해시체인 무결성, 업무유형매핑, IP 취득보정, 비정상접근 탐지, 정기점검 리포트 DB: privacy DDL 11종 + 설치용 통합 SQL(privacy.install_mysql.sql, DDL+시드 DML) 빌드복구: pom.xml 시스템 jar/JAXB 선언, iBatis2 SQL주석 '#'→'No.' 정정 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.2 KiB
4.2 KiB
신규 인증정보 저장정책 점검노트 (#28, SER-003)
문화품앗이 개인정보보호 기능개선 사업 | 작성일: 2026-07-21 대상: 추가 인증수단 3종(OTP/SMS/공동인증서)의 인증정보 저장정책 준수 여부 점검 근거: 개발항목 #28 — "OTP비밀키 암호화저장 / 휴대폰 인증번호 미저장 / 공동인증서 본문 미저장(식별값만 매핑)"
1. 점검 결론
| 인증수단 | 저장정책 | 준수 | 근거(파일:라인) |
|---|---|---|---|
| OTP(#18) | 비밀키 암호화 저장, 복호화는 검증 순간 한정, 로그·화면 미노출 | ✅ 준수 | OtpAuthService.java:85(encrypt 후 save), :97~107(검증 시 복호화) |
| SMS(#19) | 인증번호 미저장(만료시각만 세션/캐시), 3분 내 검증 후 폐기 | ✅ 설계 준수 | SmsAuthService.java:23,31,35(미저장 명시, 실발송은 발주기관 연동 대기) |
| 공동인증서(#20) | 인증서 본문 미저장, 식별값(DN)만 매핑 | ✅ 준수 | CertAuthService.java:30,69(DN만 대조, 본문 미취급) |
종합: 3종 모두 SER-003 저장정책을 준수한다. 단 OTP 프로비저닝 URI 취급에 1건 주의(아래 3절).
2. 인증수단별 상세
2.1 OTP (OtpAuthService) — ✅ 준수
- 암호화 저장:
issue/provision()에서 160bit 비밀키 생성 →OtpSecretCipher.encrypt()(AES-128/GCM) 후OtpSecretStore.save(). 평문 비밀키를 저장소에 넣지 않는다. (OtpAuthService.java:81~85) - 복호화 최소화:
verify()에서만 복호화(:107 secretCipher.decrypt), 검증 직후 지역변수로만 사용. - 로그/예외 노출 없음: 비밀키·OTP 코드를
LOG/System.out/예외 메시지에 출력하는 코드 없음(grep 결과 0건).isAvailable()은 존재여부(boolean)만 반환. - 마스터키 외부화: 암호화 마스터키는
arko.otp.master.key프로퍼티/환경변수(미설정 시 개발용 폴백 + TODO). → 운영 배포 시 마스터키 주입 필수(핸드오프).
2.2 SMS (SmsAuthService) — ✅ 설계 준수 (실발송 #19 대기)
- 클래스 주석·시그니처에 인증번호 미저장(만료시각만 세션/캐시 보관), 3분 내 검증 후 폐기 명시(
:23,31). - 실제 발송·검증 본문은
// TODO(#19): KT-TCS/MCSAgent3.0 연동규격 발주기관 확정 대기. 구현 시에도 인증번호 원문 저장 금지 원칙 유지할 것(핸드오프).
2.3 공동인증서 (CertAuthService) — ✅ 준수
verify(uniqId, code)에서 code=인증서 **DN(식별값)**을 기존 GPKI 경로(EgovLoginServiceImpl.actionCrtfctLogin→COMTNEMPLYRINFO.CRTFC_DN_VALUE)로 대조. 인증서 본문(공개키/서명 원문)은 취급·저장하지 않음(:30,69).issue()는 서버측 no-op(클라이언트 서명 기반), 실제 서명요청은CertProcessFilter(web.xml:46 주석) 재활성 핸드오프.
3. 주의·보완 권고
- OTP 프로비저닝 URI(주의):
OtpAuthService.buildOtpAuthUri()(:147~151)가 반환하는otpauth://...?secret=<base32>URI에는 평문 비밀키가 포함된다(QR 등록용 표준 동작). 이 URI는 등록 화면(#53)에서 HTTPS 전송·1회 표시·로그 미기록 원칙으로 취급해야 한다. 화면 구현(#53) 시 이 URI를 서버/접근로그·에러로그에 남기지 말 것. - OTP 마스터키 운영 주입: 개발용 폴백 키가 운영에 유입되지 않도록 배포 시
arko.otp.master.key필수 설정. - SMS 구현 시 원칙 유지(#19): 인증번호 원문 미저장, 세션/캐시엔 만료시각·해시만.
- 접속기록 연계: 2차 인증 성공/실패도 개인정보 접근 맥락에서 접속기록(#31) 대상 여부 검토(현재 pointcut은 개인정보 처리 서비스 5종 한정).
4. 관련 개발항목
- #18 OtpAuthService TOTP·AES-GCM / #19 SmsAuthService 발주기관 연동 대기 / #20 CertAuthService GPKI 위임
- #27 비밀번호 해시 점검노트 — 기존 비밀번호(SHA-256, 무솔트 보완권고)와 별개
- 저장정책 위반 소지: 점검 시점 0건(로그/화면 평문 노출 없음). OTP 프로비저닝 URI만 화면 구현 시 주의.