컴퓨터공학 300 주제 시리즈의 292번째 글이다. 전체 지도는 여기.

한 줄 요약

개인정보 보호법은 “개인을 알아볼 수 있는 정보”를 정당한 근거와 목적 안에서 최소한으로 처리하고, 안전하게 지키고, 정보주체의 권리를 보장하라고 요구한다. 이 요구의 상당수는 결국 테이블 설계, 로그 정책, 접근 제어 같은 코드로 구현된다.

왜 필요한가

개인정보 사고는 대개 거창한 해킹보다 평범한 설계 결정에서 시작된다.

  • “혹시 몰라서” 주민등록번호와 생년월일을 다 받아 둔다.
  • 디버깅하려고 요청 본문 전체를 로그에 남겼는데 비밀번호와 전화번호가 들어 있다.
  • 탈퇴한 회원 데이터가 백업과 분석용 복제 DB 에 그대로 남는다.
  • 운영 DB 를 그대로 복사해 개발 환경에서 쓴다.

법은 이것들을 “처리자의 의무 위반”으로 본다. 그리고 그 의무를 실제로 이행하는 사람은 시스템을 만드는 개발자다. 이 글은 법률 자문이 아니며, 구체적 판단은 조항 원문과 전문가 검토로 확인해야 한다.

핵심 개념

개인정보의 범위

한국 「개인정보 보호법」 제2조는 개인정보를 살아 있는 개인에 관한 정보로서 다음 중 하나에 해당하는 것으로 정의한다.

  1. 성명, 주민등록번호, 영상 등으로 개인을 알아볼 수 있는 정보
  2. 그 자체로는 알아볼 수 없더라도 다른 정보와 쉽게 결합해 알아볼 수 있는 정보
  3. 가명처리해 추가 정보 없이는 특정 개인을 알아볼 수 없는 정보(가명정보)

2번이 개발자에게 중요하다. 회원 ID, 기기 식별자, IP 주소, 쿠키 ID 는 그 자체로 이름이 없어도 다른 테이블과 조인하면 사람이 특정된다. EU 일반개인정보보호규정(GDPR) 제4조도 온라인 식별자와 위치 데이터를 개인정보의 예로 명시한다.

처리 원칙

GDPR 제5조의 원칙은 각국 법에 공통적으로 나타나는 뼈대다.

원칙 뜻 개발에서의 모습
적법성·공정성·투명성 근거가 있고, 알리고 처리한다 처리방침, 수집 시점 고지
목적 제한 정한 목적으로만 쓴다 마케팅 동의 없는 데이터를 마케팅에 쓰지 않음
최소화 필요한 만큼만 필요 없는 필드를 스키마에서 뺌
정확성 정확하게 유지 수정 기능 제공
보관 기간 제한 필요 기간이 끝나면 파기 TTL, 파기 배치, 백업 보존 주기
무결성·기밀성 안전하게 보호 암호화, 접근 통제, 접근 기록
책임성 지키고 있음을 증명 처리 기록, 감사 로그

처리의 법적 근거

동의만이 유일한 근거가 아니다. GDPR 제6조는 동의, 계약 이행, 법적 의무, 생명 등 중대한 이익, 공익 업무, 정당한 이익의 여섯 가지를 둔다. 한국 개인정보 보호법 제15조도 동의 외에 법률의 특별한 규정, 계약 체결·이행 등 여러 근거를 둔다. 어떤 데이터를 어떤 근거로 처리하는지 데이터 항목별로 정리해 두면, 근거가 사라졌을 때(예: 동의 철회) 무엇을 멈춰야 하는지 알 수 있다.

가명처리와 익명처리

구분 되돌릴 수 있나 법적 지위
가명처리 추가 정보(키·매핑표)가 있으면 가능 여전히 개인정보
익명처리 합리적으로 불가능 개인정보가 아님

GDPR 전문(Recital) 26 은 가명처리된 데이터도 개인정보이고, 익명 정보에는 규정이 적용되지 않는다고 설명한다. 한국 법은 가명정보를 통계 작성, 과학적 연구, 공익적 기록 보존 목적으로 일정 조건 아래 동의 없이 처리할 수 있게 하는 특례(제28조의2 등)를 둔다. 대신 추가 정보를 분리 보관하고 재식별을 금지한다.

이름을 지웠다고 익명이 되지 않는다. 나이대, 지역, 성별 같은 준식별자(quasi-identifier)의 조합이 한 사람만 가리키면 재식별된다.

정보주체의 권리

열람, 정정·삭제, 처리 정지, 동의 철회 같은 권리를 보장해야 한다. GDPR 은 삭제권(제17조)과 이동권(제20조)도 명시한다. 시스템 관점의 질문은 이것이다. “한 사람의 데이터를 모든 저장소에서 찾아 지울 수 있는가?” 운영 DB, 검색 색인, 캐시, 로그, 분석 웨어하우스, 백업을 모두 포함한다.

설계 단계부터: Privacy by Design

GDPR 제25조는 설계 및 기본설정에 의한 데이터 보호를 요구한다. 기본값이 가장 보호적인 설정이어야 한다는 뜻이다. 공개 범위 기본값은 “비공개”, 위치 수집 기본값은 “꺼짐”이다.

사고 대응과 제재

GDPR 제33조는 개인정보 침해를 인지한 뒤 원칙적으로 72시간 안에 감독기관에 신고하도록 한다. 제83조는 위반 유형에 따라 최대 2천만 유로 또는 전 세계 연간 매출의 4% 중 큰 금액까지 과징금을 정한다. 한국 법도 유출 시 통지·신고 의무와 과징금 규정을 두며, 개인정보보호위원회가 감독한다. 국내 세부 기한과 기준은 법령 원문과 시행령으로 확인한다.

GDPR 은 EU 밖의 사업자라도 EU 안의 사람에게 재화·서비스를 제공하면 적용될 수 있다(제3조). 해외 사용자가 있는 서비스는 확인이 필요하다.

직접 해 보기

가명처리의 흔한 실수 두 가지를 확인한다. 하나는 “해시만 하면 된다”는 착각, 다른 하나는 “이름만 빼면 익명”이라는 착각이다.

import hashlib, hmac, secrets, time
from collections import Counter

phone = "01012345678"

# 1) 단순 해시: 입력 공간이 작으면 전수 대입으로 되돌린다
h = hashlib.sha256(phone.encode()).hexdigest()
start = time.time()
found = None
for n in range(12340000, 12350000):   # 실제 공격자는 0000-0000 ~ 9999-9999 전체를 돈다
    cand = f"010{n:08d}"
    if hashlib.sha256(cand.encode()).hexdigest() == h:
        found = cand
        break
print("단순 SHA-256 역추적:", found, f"({time.time() - start:.3f}s)")

# 2) 비밀 키를 쓰는 HMAC: 키가 없으면 대입 공격을 할 수 없다. 키는 데이터와 분리 보관
key = secrets.token_bytes(32)
pseudo = hmac.new(key, phone.encode(), hashlib.sha256).hexdigest()[:16]
print("HMAC 가명:", pseudo)

# 3) k-익명성 점검: 준식별자 조합이 같은 사람이 최소 k 명인가
rows = [
    ("30대", "서울", "남"), ("30대", "서울", "남"), ("30대", "서울", "여"),
    ("40대", "부산", "남"), ("40대", "부산", "남"), ("40대", "부산", "남"),
    ("20대", "제주", "여"),
]
groups = Counter(rows)
k = min(groups.values())
print("k =", k, "/ 유일하게 식별되는 조합:", [g for g, c in groups.items() if c == 1])

실행 결과의 예다. HMAC 값은 키가 매번 새로 만들어지므로 실행마다 다르고, 시간은 기계마다 다르다.

단순 SHA-256 역추적: 01012345678 (0.018s)
HMAC 가명: 79cabd20d2ae48b0
k = 1 / 유일하게 식별되는 조합: [('30대', '서울', '여'), ('20대', '제주', '여')]

1만 개를 0.02초 안에 대입했다. 휴대폰 번호 뒷자리 8자리 전체는 1억 개라 이 속도로도 수 분이면 끝난다. 전화번호·생년월일처럼 경우의 수가 작은 값의 단순 해시는 사실상 가명처리가 아니다. 비밀 키를 쓰는 HMAC 이나 별도 매핑표를 쓰고, 키는 데이터와 다른 곳(KMS 등)에 둔다.

k-익명성 점검에서 k=1 이다. “20대·제주·여”는 한 명뿐이라 다른 정보와 결합하면 바로 특정된다. 범주를 넓히거나(20~30대), 해당 행을 억제하거나, 통계로만 공개해야 한다. k-익명성만으로 충분하지 않은 공격(동질성 공격 등)도 있어 차분 프라이버시 같은 기법이 연구·적용되고 있다.

현업에서는

  • 로그 마스킹은 라이브러리 수준에서 강제한다. 요청 본문 전체 로깅을 금지하고, 이메일·전화번호·토큰 필드는 직렬화 단계에서 가린다. 로그는 생각보다 많은 사람이 보고, 오래 남고, 여러 시스템으로 복제된다.
  • 개발·스테이징 환경에는 운영 데이터를 그대로 복사하지 않는다. 합성 데이터나 가명처리된 데이터를 쓴다. 홈랩 클러스터에서 실험할 때도 실제 지인의 연락처 같은 데이터는 넣지 않는다.
  • 스키마 리뷰 체크리스트에 “이 컬럼은 개인정보인가, 근거는 무엇인가, 보존 기간은 얼마인가, 삭제 요청 시 어떻게 지우는가”를 넣는다.
  • 개인정보 처리 시스템의 접근 기록(누가 언제 무엇을 조회했나)을 남기고 주기적으로 점검한다. 내부자 조회가 사고의 큰 부분을 차지한다.
  • 외부 SaaS(분석, 고객지원, 이메일 발송)에 데이터를 넘기면 위탁이나 제3자 제공, 국외 이전 문제가 된다. 계약과 처리방침에 반영해야 한다.

확인 문제

  1. 이름 없이 회원 ID 와 접속 IP 만 있는 로그는 개인정보가 아닌가?
  2. 가명정보와 익명정보의 차이를 법적 지위와 함께 설명하라.
  3. 전화번호를 SHA-256 으로만 해시해 저장하는 것이 가명처리로 부족한 이유는?
  4. “삭제 요청을 처리했다”고 말하려면 어떤 저장소들을 확인해야 하는가?

풀이

  1. 다른 정보(회원 테이블 등)와 쉽게 결합해 개인을 알아볼 수 있으면 개인정보다.
  2. 가명정보는 추가 정보가 있으면 재식별 가능하며 여전히 개인정보로 법의 적용을 받는다. 익명정보는 합리적으로 재식별할 수 없어 개인정보 보호 규정의 적용 대상이 아니다.
  3. 입력 공간이 작아 전수 대입으로 원래 값을 쉽게 찾을 수 있다. 비밀 키 기반 HMAC 이나 분리 보관한 매핑표가 필요하다.
  4. 운영 DB, 복제본, 캐시, 검색 색인, 로그, 분석 웨어하우스, 외부 위탁 시스템, 백업(보존 주기에 따른 파기 정책)까지다.

더 읽을거리 (References)