# 보안 구현-문서 일치성 점검표 작성일: 2026-05-28 (SHT30 전환 반영: 본 클러스터 정리) 목적: SHT30 온습도 모니터링 전환 구현이 기존 보안대책서 보완 문서, 설치 문서, 증빙 패키지 문서에 일관되게 반영되었는지 확인한다. ## 1. 구현 기준 | 구현 통제 | 코드/파일 근거 | 문서 반영 상태 | |---|---|---| | 관리자 비밀번호 해시 | `login.php`, `setup_hash.php`, `config.php` | 반영 | | 관리자 TOTP MFA | `login.php`, `setup_mfa.php`, `admin_security.php`, `ADMIN_TOTP_SECRET` | 반영 | | MFA 최초 등록 토큰 | `setup_mfa.php`, `MFA_SETUP_TOKEN` | 반영 | | 관리자 감사로그 | `admin_security.php`, `php/var/admin_audit.log` | 반영 | | raw-body API 서명 검증 (HMAC-SHA256) | `config.php` `verify_signature_raw()`=`hash_hmac('sha256', $raw_body, API_KEY)`, 펌웨어 `sig.c`/`secrets.h` (`X-Signature`) | 반영 (서명 방식 정정 후 일치, 아래 §2.1 참조) | | 측정값 범위 검증 | `api/sensor_data.php` (온도 -40~125℃ / 습도 0~100%) | 반영 | | 서버 임계 판정·쿨다운 | `config.php` `METRIC_*`(고온30/저온10·고습70/저습20, 30분 쿨다운, 히스테리시스), `api/sensor_data.php` | 반영 | | 임계 경보/정상복귀 SMS | `api/sensor_data.php`, `leak_sms_log` (`[고온경보]`/`[저온경보]`/`[고습경보]`/`[저습경보]`) | 반영 | | 장비 오프라인/복구 SMS | `cron_heartbeat.php`, `leak_sensor_status.offline_alerted`, `leak_sms_log` | 반영 | | 측정 이력 저장 | `leak_sensor_metric` 테이블 | 반영 | | 보관기간 정리 | `retention_cleanup.php --dry-run`, `--execute` (SMS/센서/측정/감사로그) | 반영 | | 백업·복구 증빙 | `scripts/backup_evidence.php` | 반영 | | 보안 증적 보고서 | `security_evidence.php?format=md` | 반영 | ### 2.1 서명 방식 정정 (이전 all-clear 정정) 실제 구현의 요청 서명은 **HMAC-SHA256** 이다. - 서버: `config.php` `verify_signature_raw()` = `hash_hmac('sha256', $raw_body, API_KEY)`, `hash_equals()` 로 상수시간 비교. - 펌웨어: `sig.c` `sig_raw_body()` = `HMAC-SHA256(key=API_KEY, msg=raw_body)`(소문자 hex), 호스트 레퍼런스 `reference.py` 동일. - 헤더 표기: `X-Signature = lowercase_hex(HMAC-SHA256(key=API_KEY, msg=raw_body))`. HMAC 구조를 채택한 이유는 키-접두 sha256(`sha256(API_KEY || body)`)의 **길이확장(length-extension) 공격**을 차단하기 위함이다. 이전 일부 문서(`README.md`, `INSTALL_PI_SERVER.md`, `SHT30_SENSOR2_SETUP.md`, `SOURCE_SECURITY_EVIDENCE.md`, `stm32f407_migration_plan.md`, `firmware/README.md`, `firmware/docs/PORTING_NOTES.md`, `firmware/docs/BUILD_OFFLINE.md`, `report_leak_detection_system.md`)는 서명을 키-접두 `sha256(API_KEY + body)` / `sha256(API_KEY || body)` 로 잘못 기술하고 있었다. **이 문서들은 본 정정으로 모두 HMAC-SHA256 표기로 수정되었으며, 코드와 일치한다.** (과거의 키-접두 sha256 기술은 실제 구현과 불일치하는 stale 문구였다.) ## 2. 수정한 기존 문서 | 문서 | 반영 내용 | |---|---| | `docs/SECURITY_EVIDENCE_PACKAGE.md` | MFA 증빙, 측정/임계 경보 증빙, 보관기간 dry-run, 백업·복구 증빙, PNG 재생성은 운영자 몫 명시 (사진 접근통제 증빙 제거) | | `docs/SOURCE_SECURITY_EVIDENCE.md` | raw-body 서명, 측정값 범위 검증, 서버 임계 판정·쿨다운, 오프라인 감지, `secrets.h` 비밀값 분리로 치환 (사진 업로드/프록시 절 제거) | | `docs/SECURITY_PLAN_PASS_READINESS.md` | 보안통제 매트릭스(측정값/임계 경보 행 추가, 사진 행 제거), 관리자 접근통제 문구, 월간 점검표, 개인정보+오발송 방지 문구, 자체 점검표, 증적 목록, 잔여위험 표 갱신 | | `docs/SECURITY_PLAN_HWP_REVIEW.md` | 최신 리비전(Y수정)(20260528) 기준 before→after, SHT30 구성요소, 임계 경보·오프라인 대응 절차, 사진정보 절 삭제·개인정보만 유지, 반영 순서 갱신 | | `docs/SECURITY_PLAN_ATTACHMENT_GUIDE.md` | 제공자료 가이드를 온습도·임계 SMS·STM32 기준으로 치환 (사진 보관기간·카메라·photo 항목 제거) | | `scripts/generate_security_plan_images.py` | 누수 사고 절차도 함수 제거, 데이터 흐름·목표 구성도·문서맵을 SHT30 측정→임계→SMS 흐름으로 교체 | ## 3. HWP에 넣을 때 특히 맞춰야 하는 문구 | 주제 | HWP 표현 기준 | |---|---| | 사업 범위 | “화재/누수/사진”이 아니라 “서버실 온습도(SHT30) 모니터링 + 임계 SMS 경보 + 장비 오프라인 알림”으로 표현 | | 관리자 인증 | “비밀번호 해시 + TOTP MFA + 세션 쿠키 보호 + 로그인 실패 제한 + 감사로그”로 표현 | | MFA 등록 | “`MFA_SETUP_TOKEN`은 최초 등록/교체 때만 임시 사용하고 등록 후 제거”로 표현 | | Google 연동 | “Google API 연동”이 아니라 “Google Authenticator 호환 TOTP”로 표현 | | 임계 경보 | “서버 임계 판정(`METRIC_*`: 고온30/저온10·고습70/저습20) + 30분 쿨다운 + 복구 히스테리시스”로 오발송 방지 표현 | | 개인정보 | 처리 개인정보는 “SMS 수신자 전화번호”만. 현장 사진/시설정보는 처리하지 않음으로 명시 | | 보관기간 | SMS/센서 로그/측정 이력/관리자 감사로그 365일을 기본값으로 쓰고 기관 기준 우선 적용 | | 백업 증빙 | 백업 수행 자체와 별도로 `backup_evidence.php` 결과를 복구 가능성 증빙으로 첨부 | ## 4. 아직 운영자가 채워야 하는 실제 환경 증적 아래 항목은 코드나 문서만으로 확정할 수 없으므로 운영 환경 기준으로 별도 확보해야 한다. - 실제 도메인 HTTPS 접속 화면과 인증서 정보 - Cafe24 배포 경로와 SSL 리다이렉트 적용 여부 - 단말(STM32) 네트워크 분리 또는 방화벽 정책 자료 - STM32 보드, SHT30 센서 설치 사진과 자산 정보 - 실제 SMS 수신자 현행화 확인표 - 실제 DB/설정파일 백업 주기와 담당자 - 실제 복구 테스트 결과 - 운영 서버의 `retention_cleanup.php --dry-run` 결과 - 운영 서버의 `scripts/backup_evidence.php` 결과 - 보안대책서 구성도/흐름도 PNG 재생성(`python scripts/generate_security_plan_images.py`) ## 5. 제출 전 금지 사항 - API 키, SMS secure key, DB 비밀번호, 관리자 원문 비밀번호, `ADMIN_TOTP_SECRET` 원문을 HWP 또는 첨부자료에 넣지 않는다. - MFA 화면 캡처에는 운영 비밀키를 노출하지 않는다. 증빙용 임시 키를 사용하거나 운영 키를 마스킹한다. - 사업 범위를 화재/누수/현장 사진으로 과대 기재하지 않는다. 현재 구현은 온습도 모니터링 + 임계 SMS + 오프라인 알림이다. - “Google API로 연동”이라고 쓰지 않는다. 실제 구현은 외부 Google API 없이 서버 내부에서 TOTP를 검증하는 방식이다.