권한관리(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.3 KiB
4.3 KiB
비밀번호 해시 알고리즘 점검노트 (개발항목 #27)
사업: 문화품앗이 개인정보보호 기능개선 (Ⅲ-3 인증체계 / SER-003 인증정보 보호) 점검일: 2026-07-21 | 점검자: Fork C(인증체계) | 대상:
EgovFileScrty.encryptPassword()성격: 점검(진단)만 수행 — 소스 미수정. 조치는 후속 개발항목에서 진행.
1. 결론 (요약)
알고리즘은 SHA-256으로 「개인정보의 안전성 확보조치 기준」의 일방향 암호화(SHA-256 이상) 요건을 충족한다. 다만 실제 운영 경로가 무솔트(no-salt) 오버로드를 사용하고, 반복(iteration)이 없으며, 해시값을 stdout으로 출력하는 잔존 코드가 있어 3건의 보완이 권고된다.
| 점검 항목 | 판정 | 근거 |
|---|---|---|
| 해시 알고리즘 SHA-256 이상 | ✅ 충족 | MessageDigest.getInstance("SHA-256") |
| 솔트(salt) 적용 | ⚠ 미흡 | 실제 경로가 무솔트 오버로드 사용, 솔트 API는 미사용 |
| 키 스트레칭(반복) | ⚠ 미흡 | 1회 다이제스트, iteration/work-factor 없음 |
| 검증 시 상수시간 비교 | ✅ 양호 | checkPassword가 MessageDigest.isEqual 사용(단, 미사용) |
| 인증정보 로그 노출 | ⚠ 미흡 | 해시값 System.out.println 잔존 |
2. 실측 상세
2-1. 알고리즘 (파일: src/main/java/egovframework/com/utl/sim/service/EgovFileScrty.java)
| 메서드 | 위치 | 알고리즘 | 솔트 | 인코딩 |
|---|---|---|---|---|
encryptPassword(String data) |
L219~237 | SHA-256 | ❌ 없음 | Base64 |
encryptPassword(String data, byte[] salt) |
L246~261 | SHA-256 (md.update(salt) 후 digest) |
✅ 있음 | Base64 |
checkPassword(String data, String encoded, byte[] salt) |
L271~281 | SHA-256 | ✅ 있음 | MessageDigest.isEqual(상수시간 비교) |
- 세 메서드 모두 단일 패스 SHA-256(반복/키 스트레칭 없음).
- 솔트 오버로드와
checkPassword는 구현되어 있으나 실제 호출 지점이 없다(주석 처리된main()테스트 L283~297에서만 참조).
2-2. 실제 사용 경로 — 무솔트 오버로드가 운영 경로
encryptPassword(String) (무솔트) 호출 지점(발췌):
| 경로 | 위치 | 성격 |
|---|---|---|
| 로그인 인증 | EgovLoginServiceImpl.java:83 (actionLogin → enpassword) |
취급자/회원 로그인 검증 |
| 비밀번호 변경 | EgovLoginServiceImpl.java:206, :237 |
|
| 회원/사용자/업체 가입·변경 | EgovUserManageServiceImpl, EgovMberManageServiceImpl, EgovEntrprsManageServiceImpl 등 다수 |
저장 시 해시 |
| 프론트 회원관리 | kr.or.arko.frt.biz.umt.web.*, kr.or.arko.frt.biz.merge.* 등 |
→ 로그인·가입·변경 등 모든 실제 비밀번호 처리 경로가 무솔트 SHA-256을 사용한다. 동일 평문 → 동일 해시가 되어 레인보우 테이블·동일비밀번호 식별에 취약.
2-3. 인증정보 로그 노출 (SER-003 / 중점점검 #61 인증정보노출 연계)
BizMberFrtManageController.java:553System.out.println("3패스워드확인::" + EgovFileScrty.encryptPassword(mberManageVO.getPassword()));→ 비밀번호 해시값을 표준출력(로그)에 기록. 디버그 잔존 코드로 판단되며 제거 대상.
3. 권고 (조치는 후속 항목에서)
- 솔트 전면 적용 — 운영 경로를 솔트 오버로드(
encryptPassword(String, byte[])) +checkPassword로 이설. 사용자별 랜덤 솔트를 생성·저장(가입 시)하고 검증은checkPassword(상수시간 비교)로 통일. 기존 무솔트 해시는 로그인 성공 시점 재해시(rehash-on-login) 방식으로 점진 마이그레이션. - 키 스트레칭 검토 — 단일 SHA-256 대신 반복(iteration) 적용 또는 표준 비밀번호 해시(PBKDF2 등)로의 상향을 발주기관과 협의. (기준상 SHA-256은 충족이나, 브루트포스 내성 강화 관점의 개선 권고.)
- 해시값 로그 출력 제거 —
BizMberFrtManageController.java:553의System.out.println삭제. 신규·변경 코드에 인증정보(비밀번호/해시/OTP비밀키) 출력 금지 규칙 적용(보안·품질 #61과 연계 점검).
본 점검은 진단 단계 산출물이며, 위 3건의 실제 코드 수정은 별도 개발항목 승인 후 진행한다.