Skip to content
Published on

연령 인증 의무화 시대 — 프라이버시를 지키는 인증 기술은 가능한가

Authors

들어가며 — 자유로운 인터넷의 끝인가

2026년 6월, Mullvad VPN의 블로그 글 하나가 Hacker News에서 큰 논쟁을 일으켰습니다. 제목은 도발적이었습니다. 소셜미디어 연령 인증 의무화가 자유로운 인터넷의 종말의 시작이라는 것입니다. GeekNews에도 빠르게 번역 공유되며 국내에서도 익숙한 주제가 다시 화두에 올랐습니다. 한국은 일찍부터 본인확인 제도를 운영해 온 나라이기 때문입니다.

논쟁의 구도는 단순하지 않습니다. 한쪽에는 미성년자 보호라는 정당한 목적이 있고, 다른 한쪽에는 익명성과 프라이버시라는 인터넷의 근본 가치가 있습니다. 그리고 그 사이에 끼어 있는 것이 우리 개발자들이 만들어야 할 기술입니다.

이 글의 질문은 명확합니다. "당신이 18세 이상임을 증명하되, 당신이 누구인지는 밝히지 않는" 인증이 기술적으로 가능한가? 그리고 가능하다면, 그것으로 충분한가? 결론을 먼저 말하면, 기술적으로는 상당 부분 가능하지만 기술이 정책 문제를 대신 풀어주지는 못합니다. 이 두 가지를 분리해서 보는 것이 이 글의 목표입니다.

현행 연령 인증의 문제

지금 대부분의 서비스가 쓰는 연령 인증 방식은 프라이버시 관점에서 형편없습니다. 크게 세 가지가 있습니다.

방식작동프라이버시 문제
자가 선언 (생년월일 입력)사용자가 직접 입력검증 안 됨, 무력함
신분증 업로드신분증 사진 제출전체 신원 노출, 데이터 유출 위험
얼굴 나이 추정카메라로 얼굴 분석생체정보 수집, 추정 오류
신용카드 확인카드로 성인 확인결제정보 노출, 카드 없는 성인 배제

자가 선언은 아무것도 막지 못합니다. 나머지 세 가지는 막기는 하지만, 막는 대가로 사용자의 전체 신원이나 생체정보를 서비스 제공자(혹은 그 하청 검증업체)에게 넘깁니다.

핵심 문제는 과잉 수집입니다. 서비스가 알아야 할 것은 단 한 비트의 정보, "이 사람은 18세 이상인가?"의 예/아니오뿐입니다. 그런데 현행 방식은 이름, 주소, 주민번호, 얼굴, 신분증 번호까지 한꺼번에 넘기게 만듭니다. 한 비트를 확인하려고 수백 비트를 노출하는 셈입니다.

여기에 데이터 유출 위험이 더해집니다. 연령 검증을 위해 수집된 신분증 이미지 데이터베이스는 그 자체로 매력적인 해킹 표적입니다. 실제로 연령 인증 의무화를 도입한 여러 지역에서 검증업체의 데이터 유출 사고가 보고됐습니다. 보호하려던 미성년자를 포함한 모든 사용자의 신원이 오히려 더 큰 위험에 노출되는 역설입니다.

프라이버시 보존 인증의 핵심 아이디어

이 문제를 푸는 기술적 통찰은 1980년대부터 존재했습니다. 핵심은 두 가지입니다.

원칙 1: 데이터 최소화 (Data Minimization)
  필요한 단 하나의 사실만 증명한다.
  "18세 이상" 한 비트만, 생년월일조차 노출하지 않는다.

원칙 2: 검증과 신원의 분리 (Unlinkability)
  발급자(국가)는 내가 어디서 인증했는지 모르고,
  검증자(서비스)는 내가 누구인지 모른다.
  발급과 검증이 서로 추적되지 않는다.

이 두 원칙을 구현하는 기술이 영지식 증명, Verifiable Credentials, selective disclosure입니다. 하나씩 살펴봅니다.

영지식 증명 — 비밀을 밝히지 않고 증명하기

영지식 증명(Zero-Knowledge Proof, ZKP)은 어떤 명제가 참임을, 그 명제가 참인 이유(비밀)는 전혀 밝히지 않고 증명하는 암호 기법입니다. 이름은 어렵지만 직관은 단순합니다.

고전적인 비유를 들어보겠습니다. 색맹인 친구에게 빨간 공과 초록 공이 서로 다른 색임을 증명하고 싶다고 합시다. 친구가 두 공을 등 뒤에서 섞을지 말지 결정하고 보여주면, 나는 섞였는지 아닌지 매번 맞힐 수 있습니다. 이 과정을 여러 번 반복하면, 친구는 "이 사람은 두 공을 구별할 수 있다"를 확신하게 됩니다. 그런데 어느 공이 무슨 색인지는 끝까지 말하지 않았습니다. 이것이 영지식의 핵심 직관입니다. 능력(혹은 사실)을 증명하되 그 내용은 누설하지 않는 것입니다.

연령 인증에 적용하면 이렇습니다.

주장: "나는 18세 이상이다"
증명: 생년월일이 적힌 서명된 자격증명을 가지고 있고,
      그 생년월일이 (오늘 - 18년) 이전임을 ZKP로 증명
공개되는 것: "참" 이라는 결과 한 비트
공개되지 않는 것: 실제 생년월일, 이름, 신분증 번호 등 전부

수학적으로는 범위 증명(range proof)이라는 기법을 씁니다. "내가 가진 비밀 값 x가 특정 범위 안에 있다"를 x를 밝히지 않고 증명하는 것입니다. 생년월일을 숫자로 보면, "이 숫자가 특정 기준일보다 작다"가 곧 "18세 이상"입니다.

ZKP의 매력은 강력하지만, 실용화의 걸림돌도 있습니다. 증명 생성의 계산 비용, 신뢰 설정(trusted setup)의 필요성, 그리고 무엇보다 일반 사용자가 이해하기 어렵다는 점입니다. 이 때문에 실제 표준화 흐름은 ZKP만이 아니라, 더 단순하고 검증된 selective disclosure 기법과 함께 갑니다.

Verifiable Credentials와 선택적 공개

W3C Verifiable Credentials(VC)는 디지털 자격증명의 표준 데이터 모델입니다. 종이 신분증을 디지털로 옮긴 것이라 생각하면 됩니다. 다만 세 주체가 명확히 분리됩니다.

+-----------+   발급    +-----------+   제시    +-----------+
| 발급자     |---------->| 보유자     |---------->| 검증자     |
| (Issuer)  |           | (Holder)  |           | (Verifier)|
| 예: 국가   |           | 예: 사용자 |           | 예: 서비스 |
+-----------+           +-----------+           +-----------+
                              |
                        지갑에 보관
                        (스마트폰)

핵심은 발급자와 검증자가 직접 통신하지 않는다는 점입니다. 국가가 발급한 자격증명을 사용자가 자기 지갑에 보관하고, 필요할 때 서비스에 제시합니다. 국가는 내가 어느 서비스에 그것을 제시했는지 알지 못합니다. 이것이 앞서 말한 unlinkability의 한 축입니다.

여기에 selective disclosure(선택적 공개)가 결합됩니다. 자격증명에는 이름, 생년월일, 주소 등 여러 속성이 들어 있지만, 제시할 때는 그중 필요한 것만 골라서 보여줄 수 있습니다. 연령 인증이라면 "18세 이상" 파생 속성 하나만 공개하고 나머지는 가립니다.

SD-JWT — selective disclosure의 실제 구조

selective disclosure를 구현하는 대표 포맷이 SD-JWT(Selective Disclosure for JWTs)입니다. IETF에서 표준화가 진행 중이며, 디지털 신분증의 실질적 기반 기술로 자리잡고 있습니다. 구조를 코드로 살펴봅니다.

일반 JWT는 모든 클레임이 페이로드에 그대로 들어 있어, 하나라도 보여주려면 전부 보여줘야 합니다. SD-JWT는 각 클레임을 해시로 대체하고, 실제 값은 별도의 disclosure로 분리합니다.

{
  "iss": "https://issuer.example.gov",
  "iat": 1749686400,
  "vct": "https://credentials.example/identity",
  "_sd": [
    "MTHmVfX6cFTW6oqYk8s3lDxgZ9c0Q1d2e3f4g5h6i7j",
    "9pK2lM3nO4pQ5rS6tU7vW8xY0zA1bC2dE3fG4hI5jK6"
  ],
  "_sd_alg": "sha-256",
  "age_over_18": true
}

위 페이로드에서 _sd 배열의 각 항목은 가려진 클레임의 해시입니다. 발급자는 이와 별도로 각 클레임의 실제 값과 솔트를 담은 disclosure를 함께 전달합니다.

disclosure 예시 (base64url 디코딩한 개념적 형태):
  ["랜덤솔트값", "given_name", "홍길동"]
  ["랜덤솔트값", "birthdate", "1990-03-15"]

제시 시점에 보유자는 공개할 disclosure만 골라서 첨부합니다. 검증자는 첨부된 disclosure를 해시해서 _sd의 해시와 대조해 무결성을 확인합니다. 첨부되지 않은 클레임은 해시만 존재하므로 검증자가 원본을 복원할 수 없습니다.

연령 인증 시나리오의 전체 흐름은 이렇게 됩니다.

1. 국가가 SD-JWT 자격증명 발급
   - age_over_18 같은 파생 불린 클레임을 미리 포함
   - 또는 birthdate를 가린 클레임으로 포함

2. 사용자가 지갑에 보관

3. 서비스가 "18세 이상 증명"을 요청

4. 지갑은 age_over_18 클레임만 공개하는 제시본 생성
   - given_name, birthdate 등은 첨부하지 않음

5. 서비스는 발급자 서명 + 공개된 클레임만 검증
   - 사용자의 실제 나이, 이름은 끝내 모름

여기서 중요한 설계 선택이 보입니다. birthdate를 가려서 넣고 검증자가 계산하게 할 수도 있지만, 그러면 birthdate를 공개해야 합니다. 더 나은 방식은 발급자가 미리 age_over_18 같은 파생 불린 클레임을 만들어 넣는 것입니다. 그러면 검증자는 생년월일을 영영 알 필요가 없습니다. 데이터 최소화 원칙의 실천입니다.

추가로, holder binding(키 바인딩)이라는 장치가 있습니다. 자격증명에 보유자의 공개키를 묶어두고, 제시할 때 보유자가 해당 개인키로 서명하게 하는 것입니다. 이렇게 하면 자격증명을 훔쳐서 재사용하는 공격을 막을 수 있습니다.

mDL과 mdoc — 또 다른 표준 줄기

디지털 신분증 표준에는 두 갈래가 있습니다. 하나가 방금 본 SD-JWT 계열이고, 다른 하나가 ISO/IEC 18013-5의 mDL(mobile Driving License)과 그 데이터 포맷인 mdoc입니다. 운전면허증의 디지털 버전을 표준화한 것으로, 이미 여러 국가와 미국 일부 주에서 채택되고 있습니다.

mdoc도 selective disclosure를 지원합니다. 술집에서 신분증을 보여줄 때 "성인 여부"만 보이고 주소는 가리는 식의 사용 사례를 정확히 겨냥했습니다. EU의 디지털 신원 지갑은 SD-JWT와 mdoc 양쪽을 모두 수용하는 방향으로 설계되고 있습니다.

디지털 신분증 표준 지형도

  ZKP 기반 ----+
               |  더 강한 unlinkability, 복잡도 높음
               |
  SD-JWT ------+--- W3C VC / OpenID4VP 생태계
               |    웹/OAuth 친화적
               |
  mdoc (ISO) --+--- 오프라인 제시, 정부 신분증 친화적

eIDAS 2.0과 EU 디지털 지갑

이 기술들을 실제 제도로 묶는 가장 큰 시도가 EU의 eIDAS 2.0과 EUDI Wallet(European Digital Identity Wallet)입니다. 모든 EU 시민에게 디지털 신원 지갑을 제공하고, 그 안에 신분증과 각종 자격증명을 담아 selective disclosure로 제시하게 한다는 구상입니다.

설계 의도 자체는 프라이버시 친화적입니다. 데이터 최소화, 사용자 통제, unlinkability가 명시적 요구사항으로 들어가 있습니다. 연령 인증은 이 지갑의 핵심 활용 사례 중 하나로 꼽힙니다.

다만 논쟁도 큽니다. 비판자들은 국가가 발급하는 단일 디지털 신원 체계가 오히려 추적과 통제의 인프라가 될 수 있다고 우려합니다. unlinkability가 프로토콜 수준에서 보장되더라도, 구현과 운영, 정책의 빈틈으로 무너질 수 있기 때문입니다. 기술 설계와 실제 운영 사이의 간극이 핵심 쟁점입니다.

디바이스 측 검증 모델

Apple과 Google이 미는 또 다른 접근은 디바이스 측 검증입니다. 신분증을 스마트폰 지갑(Apple Wallet, Google Wallet)에 보관하고, 검증의 상당 부분을 기기 안에서 처리합니다.

[서버 측 검증 — 기존]
  사용자 데이터 --> 서버로 전송 --> 서버가 검증 --> 결과
  (데이터가 서버에 도달, 노출 위험)

[디바이스 측 검증 — 새 모델]
  보안 칩(Secure Enclave)에 자격증명 보관
        |
        v
  요청에 대해 기기가 selective disclosure 제시본 생성
        |
        v
  최소 정보만 서버로 전송 (age_over_18 등)

장점은 명확합니다. 민감 데이터가 기기를 벗어나지 않고, 하드웨어 보안 모듈로 보호됩니다. 하지만 단점도 있습니다. 이 모델은 본질적으로 Apple과 Google이라는 두 플랫폼에 신뢰를 집중시킵니다. 게이트키퍼 권력이 더 강해진다는 비판, 그리고 두 회사의 운영체제를 쓰지 않는 사용자가 배제될 수 있다는 형평성 문제가 따라옵니다.

개발자가 알아야 할 설계 원칙

연령 인증이든 다른 신원 검증이든, 프라이버시를 보존하는 시스템을 설계할 때의 원칙을 정리합니다.

1. 데이터 최소화를 기본값으로
   - "18세 이상" 불린 한 비트만 요청한다.
   - 생년월일이 필요 없다면 생년월일을 받지 않는다.

2. 파생 클레임을 발급 단계에서 만든다
   - 검증자가 원본으로 계산하게 하지 말 것.
   - age_over_18, age_over_21 등을 발급자가 미리 넣는다.

3. 검증 결과를 저장하지 않는다
   - 검증 후 즉시 폐기. 세션 표식만 남긴다.
   - "검증됨"이라는 사실만 남기고 검증에 쓴 데이터는 버린다.

4. 발급-검증 비연결성을 유지한다
   - 검증 로그가 발급자에게 흘러가지 않게 한다.

5. 폴백 경로를 차별 없이 설계한다
   - 디지털 지갑이 없는 사용자도 배제되지 않도록.

6. 표준을 따른다
   - 자체 암호 프로토콜을 만들지 말 것.
   - SD-JWT, OpenID4VP, mdoc 등 검증된 표준을 쓴다.

세 번째 원칙이 특히 중요합니다. 많은 시스템이 "검증 기록"을 남긴다는 명목으로 검증에 사용한 데이터를 보관하다가 유출 사고를 냅니다. 프라이버시 보존의 핵심은 데이터를 안전하게 보관하는 것이 아니라, 애초에 보관하지 않는 것입니다.

한국의 본인확인 제도와 비교

한국은 이 논쟁에서 독특한 위치에 있습니다. 일찍부터 인터넷 실명제와 본인확인 제도를 운영해 왔기 때문입니다. 게임 셧다운제, 성인 콘텐츠 접근 시 본인확인 등이 익숙합니다.

한국 모델의 특징은 본인확인기관을 통한 중개 검증입니다. 통신사나 신용평가사 같은 지정된 기관이 본인확인 정보를 보유하고, 서비스는 그 기관을 통해 확인 결과(연계정보, 중복가입확인정보 등)를 받습니다. 서비스가 주민번호를 직접 받지 않는다는 점에서 일부 데이터 최소화가 적용되어 있지만, 결국 본인확인기관이라는 중앙 집중 지점에 데이터와 검증 이력이 쌓입니다.

이를 앞서 본 분산형 모델과 비교하면 차이가 분명합니다.

측면한국 본인확인기관 모델VC/지갑 모델
데이터 보유본인확인기관에 집중사용자 지갑에 분산
검증 이력기관이 추적 가능비연결성 설계 가능
선택적 공개제한적 (정해진 항목)클레임 단위 선택
익명성약함프로토콜 수준 보장 가능

한국의 제도는 안정적으로 작동해 왔지만, 중앙 집중과 검증 이력 추적이라는 구조적 특성은 분산형 프라이버시 보존 기술이 추구하는 방향과는 다릅니다. 앞으로 디지털 신분증 도입 논의에서 이 두 모델이 어떻게 수렴하거나 충돌할지가 관전 포인트입니다.

기술이 풀 수 없는 정책 문제

여기까지가 기술적으로 가능한 것이었습니다. 이제 정직해질 차례입니다. 프라이버시 보존 기술이 완벽하게 구현되어도, 남는 문제들이 있습니다. Mullvad의 글이 진짜로 지적한 것은 이 부분입니다.

첫째, 위축 효과(chilling effect)입니다. 익명으로 접근할 수 없게 되는 순간, 사람들은 정치적 의견 표현, 민감한 정보 검색, 소수자 커뮤니티 참여를 스스로 자제하게 됩니다. "18세 이상"만 증명해도, 익명이 사라졌다는 인식 자체가 표현의 자유를 위축시킵니다. 영지식 증명은 신원을 가려주지만, 검증이라는 행위가 존재한다는 사실 자체는 가려주지 못합니다.

둘째, 범위 확장(scope creep)입니다. 연령 인증을 위해 구축한 신원 인프라는 다른 용도로 쉽게 전용됩니다. 처음엔 미성년자 보호였지만, 다음엔 콘텐츠 검열, 그다음엔 반체제 인사 추적으로 확장될 수 있습니다. 기술이 중립적이어도 그것이 만든 인프라는 중립적이지 않습니다.

셋째, 배제의 문제입니다. 디지털 신분증이 없는 사람, 스마트폰이 없는 사람, 특정 플랫폼을 쓰지 않는 사람은 어떻게 되는가? 프라이버시를 완벽히 보존하는 시스템도, 그것을 가질 수 없는 사람을 인터넷에서 배제한다면 또 다른 차별입니다.

넷째, 검증 의무화 자체에 대한 질문입니다. 가장 근본적인 비판은 "연령 인증을 모두에게 강제하는 것이 옳은가"입니다. 미성년자 보호라는 목적이 정당하더라도, 그 수단으로 전체 인구의 익명 접근권을 거두는 것이 비례적인가? 이것은 암호학으로 풀 수 없는, 사회가 답해야 할 질문입니다.

마치며 — 균형 잡힌 결론

정리하면 이렇습니다.

기술은 우리가 두려워하는 최악의 시나리오(신분증 업로드, 얼굴 스캔, 데이터 유출)를 상당 부분 피할 수 있게 해줍니다. 영지식 증명, SD-JWT, Verifiable Credentials, 디바이스 측 검증은 "한 비트만 증명하고 나머지는 가리는" 인증을 실제로 가능하게 합니다. 개발자로서 우리가 연령 인증을 구현해야 한다면, 신분증 사진을 서버에 받는 방식이 아니라 이런 프라이버시 보존 표준을 쓰는 것이 분명히 옳습니다.

그러나 기술이 정책 문제를 대신 풀어주지는 않습니다. 위축 효과, 범위 확장, 배제, 검증 의무화의 정당성은 암호 프로토콜로 해결되지 않습니다. "프라이버시를 지키는 연령 인증이 기술적으로 가능하다"는 명제가 "따라서 연령 인증을 의무화해도 된다"로 자동으로 이어지지 않는다는 점을, 우리는 분명히 구분해야 합니다.

개발자에게 남는 실천적 결론은 두 가지입니다. 첫째, 연령 인증을 구현해야 하는 상황이라면 데이터 최소화를 극단까지 밀어붙이고 검증된 표준을 쓰십시오. 둘째, 그러나 기술의 우아함이 정책의 정당성을 자동으로 보증하지 않는다는 점을 잊지 마십시오. 좋은 기술은 나쁜 정책을 덜 나쁘게 만들 수 있을 뿐, 좋게 만들지는 못합니다.

자유로운 인터넷의 끝일지 아닐지는, 결국 기술이 아니라 우리가 어떤 정책을 선택하느냐에 달려 있습니다.

참고 자료