arko_renual/개인정보보호_인증정보저장정책_점검노트.md
infraurp 2a2ab99d10 개인정보보호 기능개선 사업 구현 (SFR-001~004, 권한관리·인증체계·접속기록)
권한관리(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>
2026-07-22 18:03:02 +09:00

44 lines
4.2 KiB
Markdown

# 신규 인증정보 저장정책 점검노트 (#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. 주의·보완 권고
1. **OTP 프로비저닝 URI(주의)**: `OtpAuthService.buildOtpAuthUri()`(`:147~151`)가 반환하는 `otpauth://...?secret=<base32>` URI에는 **평문 비밀키가 포함**된다(QR 등록용 표준 동작). 이 URI는 등록 화면(#53)에서 **HTTPS 전송·1회 표시·로그 미기록** 원칙으로 취급해야 한다. 화면 구현(#53) 시 이 URI를 서버/접근로그·에러로그에 남기지 말 것.
2. **OTP 마스터키 운영 주입**: 개발용 폴백 키가 운영에 유입되지 않도록 배포 시 `arko.otp.master.key` 필수 설정.
3. **SMS 구현 시 원칙 유지**(#19): 인증번호 원문 미저장, 세션/캐시엔 만료시각·해시만.
4. **접속기록 연계**: 2차 인증 성공/실패도 개인정보 접근 맥락에서 접속기록(#31) 대상 여부 검토(현재 pointcut은 개인정보 처리 서비스 5종 한정).
## 4. 관련 개발항목
- [#18 OtpAuthService](#) TOTP·AES-GCM / [#19 SmsAuthService](#) 발주기관 연동 대기 / [#20 CertAuthService](#) GPKI 위임
- [#27 비밀번호 해시 점검노트](개인정보보호_비밀번호해시_점검노트.md) — 기존 비밀번호(SHA-256, 무솔트 보완권고)와 별개
- 저장정책 위반 소지: 점검 시점 **0건**(로그/화면 평문 노출 없음). OTP 프로비저닝 URI만 화면 구현 시 주의.