
야심찬 프로젝트, 허무한 시작
EU는 최근 몇 년간 "미성년자 온라인 보호"를 최우선 과제 중 하나로 삼고 있어요. 포르노 사이트나 SNS 접속 시 나이를 확인하는 의무를 법제화하려는 움직임이 여러 나라에서 진행 중이고요. 그 일환으로 EU 집행위원회가 공개한 게 "EU Age Verification App", 즉 공식 연령확인 앱이에요. 개인정보는 최소한으로 공개하면서 "이 사람은 18세 이상이다" 같은 사실만 증명해주는, 제로 지식 증명(Zero-Knowledge Proof) 기반의 야심찬 설계였거든요. 그런데 앱이 공개되자마자 보안 연구자들이 2분 만에 우회에 성공했다는 소식이 전해졌어요.
어떻게 뚫었나
보안 연구자가 공개한 분석에 따르면 공격 방법은 허무할 정도로 단순했어요. 앱은 안드로이드 기준으로 Play Integrity API(기존 SafetyNet의 후속)를 이용해 "이 앱이 변조되지 않은 정품 환경에서 돌고 있다"는 걸 검증하려고 했어요. 그런데 서버 측 검증 로직이 허술했던 거예요. 앱이 서버에 "무결성 검증 결과"를 보내는 과정에서 토큰의 서명·유효기간·패키지명 검증을 제대로 하지 않았고, 결과적으로 공격자가 에뮬레이터나 루팅된 기기에서도 그대로 서버를 속일 수 있었어요.
더 황당한 건 연령 증명서(credential) 자체도 기기에 귀속되지 않았다는 점이에요. 한 번 발급받은 "18세 이상 증명"을 다른 사람에게 복사해서 전달하면 그 사람도 똑같이 성인 행세를 할 수 있었어요. 즉 신원과 기기와 증명서가 느슨하게 묶여 있었던 거죠. 암호학적으로 ZKP를 제대로 쓰려면 증명서 발급 시 기기에 고유한 비밀 키와 바인딩하고, 매번 증명할 때 그 키로 챌린지에 서명해야 하는데, 그 단계가 빠져 있거나 약했어요.
왜 이런 일이 벌어졌을까
기술적으로 보면 연령 확인이라는 요구사항 자체가 구조적으로 까다로워요. 국가가 발급한 신원(eID)을 쓰면 개인정보 노출이 너무 크고, 그렇다고 자체 발급 체계를 만들면 기기 바인딩·키 관리·제3자 검증 체인 전체를 견고하게 설계해야 하거든요. EU는 EUDI Wallet이라는 디지털 신분지갑 표준을 밀고 있는데, 이번 연령확인 앱은 그 프리뷰 격으로 서둘러 출시된 측면이 있어요.
거기에 정부 주도 프로젝트의 전형적인 문제가 겹쳤어요. 납기 압박에 밀려 보안 감사가 충분히 이뤄지지 않았고, 외부 연구자에 대한 사전 베타·버그바운티도 부족했어요. 소스코드 일부가 공개됐지만 서버 로직은 블랙박스라 레드팀 테스트가 제한적이었고요. 정부가 직접 만든 보안 앱이 공개 직후 뚫리는 건 사실 처음이 아니에요. 독일, 프랑스, 영국에서도 COVID 추적 앱, 전자투표 시스템 등이 비슷한 전철을 밟은 적이 있거든요.
제대로 된 설계는 어떻게 생겼을까
업계에서 실제 검증된 구조를 참고해볼게요. Apple의 Wallet에 담기는 mDL(모바일 운전면허증)이나 Google의 Identity Credential API는 ISO/IEC 18013-5 표준을 따라요. 핵심은 세 가지예요. 첫째, 증명서 발급 시 기기의 Secure Element(iOS의 Secure Enclave, 안드로이드의 StrongBox)에 비밀 키를 생성하고 외부로 꺼낼 수 없게 해요. 둘째, 검증자(예: 술집, 온라인 사이트)는 매번 랜덤 챌린지를 던지고 기기가 그걸 비밀 키로 서명해서 응답하는 challenge-response 프로토콜을 씀. 셋째, 선택적 공개(selective disclosure)를 통해 "18세 이상"이라는 불리언 값만 드러내고 생년월일은 숨김.
여기에 ZKP를 얹으면 "이 증명서가 국가가 발급한 진짜다"를 증명자의 ID 없이도 보일 수 있어요. 하지만 ZKP는 마법이 아니라, 프로토콜 전체 설계가 견고해야 비로소 의미가 있어요. 한 군데라도 검증이 빠지면 이번 EU 앱처럼 토큰 복사 공격에 뚫리거든요.
한국 개발자에게 주는 시사점
한국도 모바일 운전면허증, 모바일 신분증이 이미 상용화됐고, 금융권의 대면 실명확인이나 온라인 성인인증도 앱 기반으로 가고 있어요. 이번 EU 사례는 서버 측 검증이 클라이언트 측 증명 못지않게 중요하다는 교훈을 줘요. 안드로이드 Play Integrity, 애플 App Attest 결과를 받을 때는 서명·nonce·타임스탬프·패키지명·해시를 반드시 서버에서 교차 검증해야 해요.
또 ZKP나 VC(Verifiable Credential) 같은 기술을 도입하려는 팀이 있다면, 기기 바인딩과 키 수명 주기 관리를 설계 초기부터 확실히 해두는 게 좋아요. 증명서 자체가 복제 가능하면 아무리 멋진 암호학도 의미가 없거든요.
마무리
"2분 만에 뚫렸다"는 헤드라인은 자극적이지만, 본질은 정부 소프트웨어의 보안 감사 문화와 프로토콜 설계 성숙도 문제예요. 여러분이 만약 정부 보안 앱의 외부 감사 팀이라면, 가장 먼저 확인하고 싶은 항목은 뭘 것 같으세요?
🔗 출처: Hacker News
TTJ 코딩클래스 정규반
월급 외 수입,
코딩으로 만들 수 있습니다
17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공