5.8 KiB
5.8 KiB
DB 개인정보 보안·암호화 방안 (개발자도 알 수 없게)
“DB 보안을 중요시하고, 개발자도 사용자 개인정보를 알 수 없게 꼼꼼히 암호화한다”는 요구에 맞춘 설계·구현 방향입니다.
1. 목표
- DB에 저장되는 개인정보를 암호화해, DB만 접근하는 사람(개발자, DBA, 백업 유출 시)이 평문을 볼 수 없게 한다.
- 암호화 키는 DB나 소스코드 저장소에 두지 않고, 환경 변수·시크릿 관리에만 둔다.
- 비밀번호는 해시만 저장(복호화 불가). 이름·휴대전화·이메일 등 복구가 필요한 값만 대칭키 암호화로 저장한다.
2. 무엇을 어떻게 다룰지
| 데이터 종류 | 처리 방식 | 이유 |
|---|---|---|
| 비밀번호 | 해시만 (password_hash / bcrypt·argon2) |
복호화 불필요. 로그인 시 password_verify만 하면 됨. DB 유출돼도 평문 복원 불가. |
| 이름, 휴대전화, 이메일 등 | 저장 전 암호화, 조회 시 애플리케이션에서만 복호화 | DB에는 암호문만 저장. 키가 없으면 개발자도 평문을 알 수 없음. |
| 로그·감사 이력 | 개인정보 필드는 암호화 저장 또는 마스킹만 저장 | 로그에 평문 개인정보가 쌓이지 않게 함. |
3. 필드 단위 암호화 (이름·전화·이메일)
3.1 방식
- 대칭키 암호화(예: AES-256-GCM 또는 AES-256-CBC + HMAC) 사용.
- 키는 PHP
openssl등으로 생성해, 애플리케이션만 사용. DB에는 키를 저장하지 않음. - IV(초기화 벡터) 는 암호화할 때마다 랜덤 생성하고, 암호문과 함께 저장 (IV는 공개돼도 됨, 키만 비밀).
3.2 키 보관 (개발자도 알 수 없게)
- 로컬/개발:
.env에ENCRYPTION_KEY=...형태로 둠..env는 Git에 넣지 않고,.env.example에는 키 없이 변수명만 예시로 둠. - 운영: 서버 환경 변수 또는 시크릿 관리(AWS Secrets Manager, HashiCorp Vault, 네이버 클라우드 시크릿 등)에 넣고, 앱 기동 시에만 읽어 씀.
- 규칙: 키가 소스코드·DB·백업 파일에 들어가지 않도록 한다. 개발자에게 DB만 주면 암호문만 보이고, 키 없이는 복호화 불가.
3.3 적용 위치 (CI4 예시)
- 옵션 A: 암호화 헬퍼/라이브러리를 두고, Model에서
member등 저장·조회 시:- INSERT/UPDATE 전:
mb_name,mb_phone,mb_email등을 암호화해 DB에 넣음. - SELECT 후: 화면·비즈니스 로직에 넘기기 직전에만 복호화. 로그에는 복호화된 값이나 평문을 남기지 않음.
- INSERT/UPDATE 전:
- 옵션 B: Entity에서
mb_name등 접근 시 자동 암·복호화(Getter/Setter에서 처리). Model은 Entity를 쓰므로, 저장·조회 시 일관되게 암호화된 값만 DB에 쌓이게 함.
이렇게 하면 DB 덤프를 열어도 이름·전화·이메일은 암호문으로만 보이고, 키를 모르는 개발자는 평문을 알 수 없다.
3.4 키 로테이션(선택)
- 주기적으로 새 키로 다시 암호화하는 정책. 구현 시 키 버전을 필드에 두고, 복호화 시 버전별 키로 풀 수 있게 하면 된다. 초기에는 단일 키로 시작해도 됨.
4. 비밀번호는 암호화가 아니라 해시
- 저장:
password_hash($password, PASSWORD_DEFAULT)(bcrypt 등)로 해시만 저장. - 검증:
password_verify($input, $storedHash). - 복호화하지 않음. 따라서 “개발자가 DB만 보고 비밀번호를 알 수 없다”는 건 해시를 쓰는 것만으로 만족됨. 이미 11번 문서 등에서
password_verify전제로 되어 있음.
5. 비식별화(마스킹)와의 관계
- PWB-010201-001 “이름·휴대전화 가림”은 화면·로그에 보여줄 때 마스킹(홍동, 010-***-5678)하는 비식별화이다.
- DB 보안을 위해선 그에 더해 위처럼 저장 단계에서 암호화를 하는 것이 좋다.
- 저장: 암호화 → DB에는 암호문만.
- 표시: 필요한 경우에만 복호화 후, 권한에 따라 마스킹해서 보여줌 (관리자만 전체 보기 등 정책에 따라).
6. 접근 제어·운영
- DB 계정: 애플리케이션 전용 계정만 최소 권한(SELECT/INSERT/UPDATE/DELETE 등 필요한 것만) 부여. 개발·운영 DB는 역할별로 분리하고, 개인정보가 있는 테이블에 대한 직접 조회를 제한할 수 있으면 좋음.
- 백업: 백업 파일도 암호문만 포함하므로, 키가 유출되지 않는 한 개인정보 평문이 노출되지 않음. 백업 파일 자체도 암호화 저장 권장.
- 감사 로그: 개인정보 조회/복호화 이벤트를 로그에 남기면, 나중에 “누가 언제 복호화했는지” 추적 가능. (구현 여부는 정책에 따라.)
7. 구현 시 체크리스트
- 개인정보 필드(mb_name, mb_phone, mb_email 등) 저장 전 AES-256 등으로 암호화.
- 암호화 키는
.env또는 시크릿 관리에만 두고, Git/DB에 포함하지 않음. - 비밀번호는 해시만 저장, 복호화 로직 없음.
- 복호화는 애플리케이션에서만, 필요한 권한이 있을 때만 수행. 로그에는 평문·복호화 결과를 남기지 않음.
- 화면·로그에는 필요 시 마스킹(비식별화) 적용.
- (선택) 키 로테이션·감사 로그 설계.
이렇게 하면 “개발자도 사용자 개인정보를 알 수 없게” DB 보안을 꼼꼼히 맞추는 방향이 됩니다. 구현은 Phase 1 후반 또는 Phase 2에서 암호화 라이브러리/헬퍼 도입과 member 등 개인정보 테이블 적용부터 진행하면 됩니다.