비밀번호를 암호화하는 것은 당연하지만 다른 개인 식별 정보에 대해서는 어떻게 보호해야할 지 깊이 생각해 본 적이 없는 것 같다!!
개인정보 유출 시 피싱/사칭 등 범죄에 이용될 가능성이 있기 때문에 보호가 필요하다.
주로 DB, 로그 등을 통해 외부로 유출 되거나 또는 내부자 위험도 있다.
암호화 해두면 유출되더라도 바로 식별 불가능하기 때문에 암호화가 필수다!!
📌 개인 식별 정보 보호 방법 정리
개인 식별 정보는 검색이나 화면에 일부 노출이 필요한 경우도 있다!!
그렇기 때문에 복호화가 가능한 암호화를 이용해야한다.
조회 성능을 위해 해시/마스킹/토큰화 방법을 같이 이용한다.
대상
- 이메일
- 휴대폰 번호
- 주소
- 사번 / 고객번호
💫 비밀번호는 예외 처리 (검색 대상 아님)
비밀번호는 조회·조건 검색이 필요하지 않으므로 단방향 해시만 저장(BCrypt 등), 복호화 가능한 방식 금지.
📌 1. 기본 개념 정리 🔍
✅ 1-1. 암호화가 필요한 이유
암호화를 안 하면 → 평문 데이터가 내부/외부 공격 둘 다에 취약
암호화를 하면 → 유출되더라도 “바로 식별 불가능한 상태”로 만드는 것
✅ 1-2. 왜 “전체 암호화”만 쓰면 안 되나?
- AES로 전체 암호화 → ❌ WHERE email = ? 검색 불가
- 복호화 후 비교 → ❌ 성능·보안 모두 나쁨
👉 그래서 보조 컬럼을 둔다.
📌 2. 가장 많이 쓰는 구조
✅ 구조 요약
email_enc ← AES 암호화 (복호화 가능)
email_hash ← 검색용 단방향 해시
email_mask ← 화면 표시용
📌 3. 데이터 별 예시
✅ 3-1. 이메일
🔹 DB 컬럼 설계
EMAIL_ENC VARCHAR(512) -- AES 암호화
EMAIL_HASH CHAR(64) -- SHA-256
EMAIL_MASK VARCHAR(100) -- 화면용
🔹 저장 시 로직
1️⃣ 사용자 입력
abc.def@gmail.com
2️⃣ 애플리케이션 처리
String email = inputEmail;
String emailEnc = aesEncrypt(email); // 복호화용
String emailHash = sha256(email.toLowerCase()); // 검색용
String emailMask = maskEmail(email); // 화면 표시
3️⃣ DB 저장
EMAIL_ENC = "Q9A8D..."
EMAIL_HASH = "b4c9a289..."
EMAIL_MASK = "ab***@gmail.com"
🔹 검색 시
SELECT *
FROM USER_PRIVATE
WHERE EMAIL_HASH = :sha256(email)
✔ 복호화 불필요
✔ 인덱스 가능
✔ 성능 좋음
✅ 3-2. 휴대폰 번호
🔹 정규화 후 처리 (형식 통일)
- 010-1234-5678
- 01012345678
- +82-10-1234-5678
🔹 처리 흐름
String phone = normalizePhone(input); // 01012345678
phoneEnc = aesEncrypt(phone);
phoneHash = sha256(phone);
phoneMask = "010-****-5678";
🔹 DB 설계
PHONE_ENC
PHONE_HASH
PHONE_MASK
✅ 3-3. 주소 🏠
❓ 주소는 해시만으로 부족한 이유
- 부분 검색 필요
- 시/도, 구 단위 검색
🔹 실무 패턴
ADDR_ENC ← 전체 주소 AES
ADDR_SIDO ← 서울특별시
ADDR_SIGUNGU ← 강남구
ADDR_DONG ← 역삼동
✔ 행정단위는 평문
✔ 상세주소만 암호화
🔹 검색 예시
WHERE ADDR_SIDO = '서울특별시'
AND ADDR_SIGUNGU = '강남구'
✅ 3-4. 사번 / 고객번호 (외부 노출 기준)
🔥 내부용 vs 외부용 분리
EMP_NO_INTERNAL ← 평문 (PK)
EMP_NO_EXTERNAL ← 토큰화
🔹 토큰화 예시
EMP-2024-000123 → X9FQ-82KD-P0
✔ 외부 API
✔ URL 노출
✔ 로그 노출
👉 절대 내부 사번 그대로 쓰지 말 것
📌 4. 로그 & 백업 보호 규칙 ⚠️
❌ 개인 정보 전체 출력
log.info("email={}", email);
✔️ 올바른 로그 -> 마스킹
log.info("email={}", emailMask);
또는
log.info("emailHash={}", emailHash);
📌 5. 키 관리 핵심 🔐
❌ 금지
- 소스코드에 AES 키 하드코딩
- git에 키 업로드
✅ 권장
- 환경변수
- Vault / KMS
- 키 로테이션
📌 6. 결론 🚀
“원본은 암호화, 검색은 해시, 화면은 마스킹, 외부는 토큰”
| 목적 | 방식 |
| 저장 | AES 암호화 |
| 검색 | SHA-256 해시 |
| 화면 표시 | 마스킹 |
| 외부 노출 | 토큰화 |
| 로그 | 마스킹 / 해시 |
'DB > 데이터 관리' 카테고리의 다른 글
| Elasticsearch > analyzer (0) | 2026.01.25 |
|---|---|
| CTE(Common Table Expression)란? (0) | 2025.11.29 |
| Elasticsearch란? (0) | 2025.04.10 |
| JDBC / SQL Mapper / ORM (JPA, Hibernate, MyBatis) (0) | 2024.09.25 |