PDF 변환기가 오류를 일으킨 파일: 모든 리더가 열 수 있지만 소유자 암호는 열 수 없는 경우
요약
PDF 문서의 복잡한 암호화 구조와 변환기 오류 처리 방식을 다룹니다. 특히, 사용자 암호가 비어 있는 상태에서 발생하는 'File has not been decrypted' 오류를 빈 문자열로 `decrypt` 호출을 통해 해결하는 방법을 제시합니다. 또한, 실패 모드를 개선하여 RAG 파이프라인의 오염을 막는 구조화된 오류 반환 방식을 도입했습니다.
핵심 포인트
- PDF 암호화는 사용자/소유자 두 개의 독립적인 암호를 가집니다.
- 빈 문자열로 `decrypt`를 호출하는 트릭으로 암호가 걸린 파일을 처리할 수 있습니다.
- 변환기는 이제 '추출 실패' 등 구조화된 오류를 반환하여 RAG 파이프라인의 신뢰도를 높였습니다.
- PDF 암호화를 부울(boolean)이 아닌 3단계 상태로 명시적으로 처리해야 합니다.
한 법무팀이 제 PDF-to-Markdown 변환기에 40페이지짜리 서비스 계약서를 보냈습니다. 모든 데스크톱 리더기는 파일을 정상적으로 열었습니다. 하지만 제 변환기는 'File has not been decrypted'라는 오류를 발생시켰습니다.
저는 파일 손상이라고 생각했습니다. 그렇지 않았습니다. PDF는 두 개의 독립적인 암호를 가집니다. 하나는 파일을 여는 데 필요한 사용자 암호(user password)이고, 다른 하나는 인쇄, 복사 및 텍스트 추출을 제한하는 소유자 암호(owner password)입니다. 출판사나 법무팀은 소유자 암호를 좋아합니다. 문서는 어디서든 열리지만 텍스트를 제공하기를 거부합니다. 제 추출 라이브러리는 사용자 암호가 비어 있음에도 불구하고 암호화 사전(encryption dictionary)을 보고 작동을 멈췄습니다.
해결책은 단 하나의 의도적인 코드 라인이었습니다. 즉, 추출이 'not-decrypted' 오류로 실패할 경우, 포기하기 전에 빈 문자열("")로 decrypt를 호출하는 것이었습니다. 사용자 암호가 비어 있는 상태가 바로 이러한 파일들이 배포되는 방식입니다. 뷰어도 같은 트릭을 조용히 사용하지만, 그 사실을 언급하지 않을 뿐입니다. decrypt("")를 호출한 후에는 모든 페이지가 정상적으로 추출되었습니다. 권한 플래그는 보안(security)이 아니라 자문적(advisory)인 것이었습니다.
하지만 더 깊은 교훈은 실패 모드(failure modes)에 관한 것이었습니다. 이 사건 이전까지, 읽을 수 없는 PDF는 빈 Markdown을 반환했습니다. 이는 RAG 파이프라인에게 최악의 결과입니다. 성공처럼 보이고, 청크로 분할되며, 임베딩되고, 아무것도 없는 것으로 인덱스를 조용히 오염시킵니다. 이제 변환기는 'PDF가 아님', '텍스트 레이어가 없는 이미지 전용 스캔본', '사용자 암호 필요', 그리고 '추출 실패'를 구별하는 구조화된 오류를 반환합니다. 호출자는 권한이 잠긴 계약서를 인덱싱하여 무효화시키는 대신, 사람에게 전달할 수 있습니다.
같은 것을 구축하는 누구에게든 전하고 싶은 두 가지 작은 점이 있습니다:
- PDF 암호화를 부울(boolean) 상태가 아닌 3단계 상태로 취급하세요: 암호 없음, 빈 사용자 암호 암호화, 실제 암호화. 중간 상태를 명시적으로 처리해야 합니다.
- 문서 파이프라인이 절대 빈 문자열 성공을 반환하도록 두지 마세요. 빈 출력은 항상 '아무 문제도 없었다'와 구별되어야 합니다.
결국 저는 이 모든 것을 PDF-to-Markdown API(https://x402.freeq.one/tools/pdf_to_markdown.html)로 패키징했습니다. 즉, 직접 URL이나 base64 바이트를 입력하면 제목(headings), 목록(lists), 표(tables)가 출력됩니다. 만약 계약서나 보고서를 에이전트의 컨텍스트에 공급할 계획이라면, 그 변환기가 소유자 암호가 설정된 파일에서 어떤 처리를 하는지 확인한 후에 빈 출력을 신뢰해야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기