고객이 '극비(Top Secret)'로 표시된 PDF를 보냈습니다. 그래도 저는 Claude가 그것을 읽어야 했습니다.
요약
민감 정보가 검게 가려진 PDF에서 데이터를 추출하는 것은 기존 방식으로는 어렵습니다. 일반적인 편집기나 온라인 도구는 보안 문제 또는 텍스트 레이어의 특성상 정보를 완전히 제거하지 못합니다. 필자는 브라우저 기반의 자체 도구를 개발하여, PDF.js로 위치 정보와 함께 텍스트를 가져오고 정교한 검증 알고리즘을 적용해 데이터를 안전하게 추출하는 방법을 제시했습니다.
핵심 포인트
- 단순히 검은 상자로 가리는 것은 텍스트 레이어에 남아 LLM이 인식할 수 있습니다.
- 민감 정보 처리를 위해 제3자 서버 업로드를 피하고 클라이언트 측 도구를 사용해야 합니다.
- PDF.js를 활용하여 모든 텍스트 항목의 위치(좌표) 정보를 가져오는 것이 핵심입니다.
- 정규 표현식보다 Luhn, ABA 체크섬 등 검증기(validators)가 데이터 정확도에 필수적입니다.
저는 고객을 위한 도구를 만들고 있었는데, 파싱을 정확하게 하려면 그들이 매일 사용하는 실제 문서를 봐야 했습니다. 그들은 이메일에 한 줄과 함께 파일을 보내왔습니다. "극비(Top secret)."
새로운 문서 형식을 다룰 때 저의 일반적인 방식은 샘플을 Claude에 넣고 구조를 파악하는 것입니다. 어떤 필드가 반복되는지, 표가 어디서 시작하는지, 무엇이 선택 사항인지, 엣지 케이스는 어떤 모습인지를 확인합니다. 하지만 이 파일로는 그럴 수 없었습니다. 이름, 전화번호, 계좌번호로 가득 차 있었고, 저는 그것을 비공개로 유지하겠다고 약속했기 때문에, '레이아웃만 보기 위해' 제3자 서비스에 붙여넣는 것은 제가 꺼리는 일이었습니다.
실제로 저에게 필요했던 것은 지루한 것이었습니다. 같은 문서, 같은 레이아웃, 같은 라벨이지만 개인 정보가 검게 가려진 상태였습니다. Claude는 구조를 파악할 수 있지만, 아무도 비밀을 알 수는 없습니다.
이것은 생각보다 더 어려웠습니다.
검은 상자는 아무것도 제거하지 않는다
첫 번째 시도는 다음과 같습니다: PDF 편집기에서 파일을 열고 민감한 부분 위에 검은 직사각형을 그린 다음 저장합니다. 그리고 모두가 해야 하지만 거의 아무도 하지 않는 확인 절차는 이렇습니다:
- "편집된(redacted)" PDF를 엽니다.
- Ctrl+A (Mac에서는 Cmd+A)로 복사합니다.
- 일반 텍스트 편집기에 붙여넣습니다.
모든 것이 여전히 남아 있었습니다. PDF는 텍스트와 그림을 분리하여 저장하기 때문에, 검은 직사각형은 그저 위에 그려진 모양일 뿐입니다. 아래에 있는 글자는 손대지 않았으며, 텍스트 레이어를 읽는 모든 것(복사-붙여넣기, 검색 또는 파일에 제공하는 LLM)은 그것들을 정상적으로 인식합니다. 이는 몇 달마다 유출되는 법원 기록이나 정부 보고서에서 발생하는 똑같은 실수입니다.
온라인 편집 도구: 같은 문제, 다른 형태
다음 옵션은 PDF를 대신 편집해 주는 웹사이트였습니다. 즉, 비밀을 제거하기 위해 극비 파일을 낯선 사람의 서버에 업로드해야 한다는 뜻입니다. 그것이 바로 제가 피하고 싶었던 일입니다.
그래서 저는 저만의 도구를 작성했고, 브라우저 내에서 완전히 실행되도록 만들었습니다.
작동 방식
1. 위치 정보와 함께 텍스트 가져오기. PDF.js는 변환(transform) 정보를 포함하여 모든 텍스트 항목을 제공하므로, 각 문자를 페이지의 사각형 영역으로 매핑할 수 있습니다. 이것이 "41870253" 위에 박스를 그리고 다른 곳은 아무것도 건드리지 않게 할 수 있는 방법입니다.
2. 패턴으로 명확한 정보를 찾고, 검증하기. 이메일 주소, 전화번호(libphonenumber-js), IBAN, 카드 번호, 영국 소트 코드, 미국 라우팅 번호 등입니다. 여기서 중요한 것은 정규 표현식(regexes) 자체보다 검증기(validators)입니다. mod-97 검사 없이는 문서에 있는 절반의 참조 번호가 마치 IBAN처럼 보입니다. Luhn 알고리즘이 없다면 모든 긴 주문 번호가 "카드 번호"로 인식됩니다. ABA 체크섬이 없다면 모든 9자리 송장 번호가 라우팅 번호로 간주됩니다:
// US routing numbers: weights 3-7-1, the sum must be a multiple of 10.
export function abaRoutingValid(input: string): boolean {
const d = input.replace(/\D/g, '');
...
계좌 번호는 체크섬이 전혀 없기 때문에, "Account number" 또는 "Acct #"와 같은 레이블을 따를 때만 플래그가 지정됩니다.
3. 이름(Name)은 가장 어려운 부분입니다. 어떤 정규 표현식도 "Sophie Whitmore"를 찾아낼 수 없습니다. 레이블("Name:", "Transfer to", 주소 위에 위치한 대문자로 된 줄 등)이 도움이 되며, 나머지 경우에는 Web Worker 내에서 Transformers.js와 함께 선택적 소규모 개체명 인식 모델(영어의 경우 bert-base-NER, 프랑스어의 경우 camembert-ner)을 사용합니다. 이 모델은 한 번 다운로드되어 캐시되며, WebGPU를 통해 실행되고 WASM으로 폴백됩니다.
4. 스캔 이미지. 페이지에 텍스트 레이어가 없는 경우, Tesseract.js가 먼저 WASM으로 읽어 들인 후, OCR(광학 문자 인식) 단어들이 동일한 검출기를 거칩니다.
5. 인간의 판단이 필요합니다. 아무것도 자동으로 제거되지 않습니다. 발견된 모든 항목은 플래그 지정 사유와 함께 표시되며, 사용자가 이를 유지하거나 제거할 수 있습니다. 탐지 과정은 항상 무언가를 놓치거나 어딘가에서 과도하게 인식할 수 있으므로, 검토 단계는 선택 사항이 아닙니다.
6. 편집이 아닌 다시 그리기(redrawing)를 통한 내보내기. 각 페이지는 150 DPI로 캔버스에 렌더링되고, 상자 안에 색상이 채워지며, 이 이미지들로부터 텍스트 레이어와 메타데이터가 없는 새로운 PDF가 작성됩니다. 단점은 출력물이 검색 가능하지 않다는 것입니다. 저의 사용 사례에서는 괜찮았습니다. 레이아웃이 유지되며, Claude는 페이지 이미지를 문제없이 읽을 수 있고, 찾을 숨겨진 텍스트도 없습니다.
'어떤 것도 기기를 벗어나지 않는다'를 검증 가능하게 만들기
"파일을 업로드하지 않는다"고 말하는 것은 값싼 주장입니다. 그래서 이 페이지는 엄격한 Content-Security-Policy(CSP)가 적용되어 있으며, 여기서 connect-src는 자체 오리진만 허용하고, AI 단계를 선택할 경우에만 일회성 다운로드를 위한 모델 호스트를 추가로 허용합니다. 브라우저 자체가 문서를 다른 곳으로 전송하려는 모든 시도를 차단합니다. 또한 페이지를 로드한 후 와이파이를 끄고 전체 과정을 오프라인으로 수행할 수도 있습니다.
타인이 수행한 수정(redaction) 검사하기
이것이 작동하는 것을 확인한 후, 저는 반대 방향도 원했습니다. 즉, 다른 사람이 "수정"한 PDF를 넣고 그 텍스트가 여전히 존재하는지 알아내는 것입니다. 아이디어는 텍스트 레이어가 말하는 것과 인간의 눈에 보이는 것을 비교하는 것입니다.
페이지를 캔버스에 렌더링한 다음, 각 단어 아래의 픽셀을 살펴봅니다. 실제 텍스트는 항상 자체 상자 안에 대비(contrast)를 가지고 있습니다: 밝은 배경 위의 어두운 글리프(glyph). 영역이 한 가지 평평한 색상인 단어는 화면에서 읽을 수 없지만, 파일에는 여전히 존재합니다.
// rgba: 렌더링된 페이지의 단어 하나 아래에 있는 픽셀들.
const n = rgba.length / 4;
const lum = [];
...
또한 표시되었으나 실제로 적용되지 않은 수정 주석(redaction annotations)과 살아남은 모든 메타데이터(저자, 제목, 생성 앱 등) 목록도 제공합니다. 숨겨진 문자열은 처음 두 글자만 보여주기 때문에, 결과의 스크린샷을 찍어도 데이터가 다시 유출되는 것을 막아줍니다.
여전히 놓치는 것들
- 실제 텍스트 대신 벡터 경로로 그려진 텍스트.
- 투명도를 가진 검은색 상자.
- 모델에 의해 레이블이 지정되거나 인식되지 않은 이름. 이것이 리뷰 단계가 존재하는 이유입니다.
비식별화(Redaction) 도구는 sumipdf.com에 있으며, 검사기(checker)는 sumipdf.com/check에 있습니다. 둘 다 무료로 사용해 볼 수 있습니다. 만약 민감한 파일을 AI 도구나 계약자에게 보여줘야 했던 경험이 있다면, 어떻게 처리했는지 궁금합니다. 또한 검사기가 파일에서 오류를 발견했다면 그것도 알고 싶습니다.
전반적인 상황을 감안하여 Claude가 이 글을 다듬는 것을 도와주었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기