본문 바로가기

파일 형식 백과사전

PDF에 암호를 걸었는데 그냥 열립니다, 암호 칸이 두 개인 이유

PDF에 암호를 거는 화면을 열어 보면 암호를 넣는 칸이 하나가 아닙니다. 위쪽에는 문서를 열 때 쓸 암호, 아래쪽에는 권한을 바꿀 때 쓸 암호를 따로 받습니다.

여기서 아래쪽 칸만 채운 채 저장하면, 나중에 그 파일은 암호를 묻지 않고 그냥 열립니다. 잘못 만든 것이 아니라 원래 그렇게 동작하는 것입니다. 같은 PDF에 두 방식을 각각 걸어 파이썬으로 열어 보며 무엇이 어떻게 다른지 확인해 봤습니다.

 

PDF 두 가지 암호의 동작 비교 도식. 열기 암호를 건 파일은 빈 암호로 열기가 실패하고 내용 자체가 잠기는 반면, 권한만 제한한 파일은 빈 암호로도 열리고 인쇄와 복사 금지 표시만 들어 있음

 

이름부터 역할이 다릅니다

PDF 규격에는 암호가 두 종류 있습니다. 하나는 사용자 암호로, 흔히 열기 암호라고 부릅니다. 문서를 여는 자격을 확인하는 암호입니다.

다른 하나는 소유자 암호입니다. 이쪽은 문서를 여는 것과는 상관이 없고, 인쇄나 복사 같은 권한을 풀 때 필요한 암호입니다. 그래서 소유자 암호만 걸면 문서는 누구나 열 수 있고, 대신 인쇄와 복사를 하지 말라는 표시가 파일에 붙습니다.


같은 PDF에 각각 걸어 봤습니다

워드로 만든 한 페이지짜리 PDF를 준비하고, 파이썬 pypdf로 두 벌을 만들었습니다. 하나는 열기 암호를 건 파일, 다른 하나는 열기 암호 없이 인쇄와 복사와 편집만 막은 파일입니다. 그리고 각각을 암호 없이 열어 봤습니다.

확인 항목 열기 암호를 건 파일 권한만 제한한 파일
암호화된 파일인가
암호 없이 열리는가 아니오 (실패) 예 (성공)
내용을 읽을 수 있는가 불가 가능
권한 표시 확인 불가 인쇄, 복사, 편집 차단

두 파일 모두 "암호화된 문서"인 것은 같습니다. 그런데 막는 지점이 완전히 다릅니다. 열기 암호를 건 파일은 문 앞에서 걸리고, 권한만 제한한 파일은 문은 열린 채 안내문만 붙어 있는 셈입니다.

확인에 쓴 코드는 짧습니다. 자기 파일이 어느 쪽인지 알아볼 때 그대로 쓰시면 됩니다.

from pypdf import PdfReader

r = PdfReader("문서.pdf")
print(r.is_encrypted)                  # 암호화 여부
print(r.decrypt(""))                   # 0이면 열기 암호가 걸린 파일
print(r.user_access_permissions)       # 권한 표시 값

여기서 decrypt가 돌려주는 숫자가 자격을 뜻합니다. 0은 열지 못했다는 뜻이고, 1은 일반 사용자 자격으로 열렸다는 뜻이며, 2는 소유자 자격으로 열렸다는 뜻입니다. 실제로 권한 제한 파일에 소유자 암호를 넣어 보니 반환값이 2로 바뀌었습니다.

 

 

권한 제한은 파일에 적힌 표시입니다

권한만 제한한 파일에서 권한 값을 읽어 보니 4294967264라는 숫자가 나왔습니다. 이 숫자 하나에 항목별 허용 여부가 비트로 담겨 있습니다. 풀어 보면 이렇습니다.

항목 상태
인쇄 차단
내용 수정 차단
텍스트와 그림 복사 차단
주석 달기 허용
양식 채우기 허용
페이지 조립 허용

중요한 것은 이 값의 성격입니다. 권한 제한은 내용을 잠그는 자물쇠가 아니라, 파일에 적어 둔 요청 사항에 가깝습니다. PDF를 여는 프로그램이 그 표시를 읽고 인쇄 버튼과 복사 기능을 막아 주기로 약속한 구조입니다.

그래서 정상적인 뷰어에서는 잘 지켜지지만, 이 표시를 존중하지 않는 프로그램까지 강제하지는 못합니다. 사내에서 실수로 인쇄되거나 복사되는 일을 줄이는 용도로는 쓸 만하지만, 외부로 나가면 안 되는 문서를 지키는 수단으로 삼기에는 약합니다.

 

 

어디까지 잠기는지도 확인해 봤습니다

두 파일에서 각각 무엇을 읽을 수 있는지 항목별로 재 봤습니다. 암호를 넣지 않은 상태에서 시도한 결과입니다.

읽어 본 항목 암호 없는 원본 열기 암호 권한 제한
페이지 수 1 읽기 실패 1
만든 프로그램과 작성 시각 보임 읽기 실패 보임
본문 텍스트 283자 추출됨 읽기 실패 복사 금지 표시가 붙음

열기 암호를 건 파일은 페이지가 몇 장인지조차 알려주지 않았습니다. 요청할 때마다 복호화되지 않은 파일이라는 오류가 났습니다.

반면 권한만 제한한 파일에서는 문서 속성이 그대로 읽혔습니다. 이번 파일에서는 만든 프로그램이 Microsoft Word 2013이고 언제 만들어졌는지까지 나왔습니다. 여기에 작성자 이름이나 회사명이 들어 있었다면 그것도 함께 보였을 것입니다. 워드 문서에 남는 이런 정보를 확인하고 지우는 방법은 따로 다룬 적이 있습니다.

 


같은 암호라도 잠그는 방식은 여러 가지입니다

암호를 건다고 다 같은 방식이 아닙니다. 같은 PDF를 세 가지 방식으로 암호화하고 파일 안의 암호화 정보를 읽어 봤습니다.

방식 파일 안 표기 키 길이 파일 크기
RC4-128 V 2, R 3 128 59,382 B
AES-128 V 4, R 4 128 68,753 B
AES-256 V 5, R 6 256 69,001 B

RC4는 오래된 방식이고, 지금 새로 만드는 문서라면 AES 쪽이 표준입니다. 자기 파일이 어떤 방식으로 잠겨 있는지는 암호화 정보를 직접 꺼내 보면 알 수 있습니다.

r = PdfReader("문서.pdf")
enc = r.trailer["/Encrypt"].get_object()
for key in ("/Filter", "/V", "/R", "/Length", "/P"):
    print(key, enc.get(key))

AES-256으로 잠근 파일에서는 이렇게 나왔습니다.

/Filter /Standard
/V 5
/R 6
/Length 256
/P 4294967292

맨 아래 /P가 앞에서 본 권한 값입니다. 이 파일은 열기 암호만 걸고 권한은 따로 막지 않아서, 권한을 모두 허용한다는 뜻의 4294967292가 들어 있습니다. 인쇄와 복사와 편집을 막았던 파일에서는 같은 자리에 4294967264가 있었습니다. 두 숫자의 차이가 곧 무엇을 막았는지입니다.

 

 

그래서 어떻게 고르면 되나

정리하면 선택 기준은 간단합니다. 이 문서를 볼 사람을 제한해야 하는가가 갈림길입니다.

계약서나 급여 명세처럼 받는 사람이 정해져 있고 유출되면 곤란한 문서라면 열기 암호를 겁니다. 이때 암호는 파일과 같은 메일에 적어 보내지 말고 다른 경로로 알려야 합니다. 같은 메일에 함께 적으면 잠근 의미가 없습니다.

반대로 여러 사람이 봐야 하되 인쇄나 무단 편집을 줄이고 싶은 자료라면 권한 제한이 맞습니다. 다만 그것이 보증이 아니라는 점은 알고 쓰는 편이 좋습니다.

지켜야 할 것이 내용 자체라면 열기 암호, 취급 방식에 대한 안내라면 권한 제한입니다.

 

 

자주 묻는 질문

Q. 열기 암호를 잊어버렸습니다.
정상적인 방법으로는 열 수 없습니다. 암호를 모르면 내용을 볼 수 없게 만드는 것이 이 기능의 목적이기 때문입니다. 원본 문서가 남아 있다면 그쪽에서 PDF를 다시 만드는 것이 유일하게 확실한 방법입니다. 중요한 문서에 암호를 걸 때는 암호 보관 계획을 먼저 정해 두시길 권합니다.

Q. 암호를 걸면 파일이 무거워지나요?
거의 그렇지 않습니다. 다만 비교할 때 주의할 점이 있습니다. 원본 42,193바이트를 암호 없이 다시 저장만 해도 59,918바이트가 됐습니다. 파일을 다시 쓰는 과정에서 생긴 변화이지 암호 때문이 아닙니다. 이 대조군과 비교하면 RC4는 오히려 조금 작았고, AES 방식은 9KB 남짓 늘었습니다.

Q. 워드나 한글에서 바로 걸 수 있나요?
워드는 PDF로 저장할 때 옵션 창에서 문서를 암호로 암호화하는 항목을 켤 수 있습니다. 이때 설정되는 것은 열기 암호입니다. 권한을 세밀하게 지정하려면 Adobe Acrobat처럼 PDF 보안 설정을 지원하는 편집 프로그램이 필요합니다.

Q. 암호를 걸면 내용이 검색되지 않게 되나요?
열기 암호를 건 파일은 암호를 모르는 상태에서 내용을 읽을 수 없으니 검색 색인에도 잡히지 않습니다. 반면 권한만 제한한 파일은 열리는 파일이라 상황이 다릅니다.

 

 

PDF 암호 설정 화면에서 칸을 둘 다 채울 필요는 없습니다. 무엇을 막고 싶은지 먼저 정하고, 그에 맞는 칸 하나만 채우면 됩니다. 지금 보관 중인 중요한 PDF가 있다면 위 코드 세 줄로 어느 쪽이 걸려 있는지부터 확인해 보세요.

 

이 글의 동작 확인과 권한 값은 파이썬 pypdf 6.14.2로 같은 PDF에 두 방식을 실제로 적용해 얻은 결과입니다.

 

 

 

가변 폰트(Variable Font)란, 파일 하나로 굵기가 바뀌는 원리를 열어서 확인했습니다

폰트를 내려받다 보면 이름 뒤에 "Variable"이 붙은 파일을 마주칠 때가 있습니다. Thin, Light, Regular, Bold처럼 굵기별로 파일이 따로 있는 게 아니라 딱 하나뿐인데, 정작 적용해 보면 슬라이더로 굵

richyeon.com

 

 

엑셀 파일이 안 열릴 때, 손상된 건지 확장자만 다른 건지 구조로 구분하기

거래처에서 받은 xlsx 파일을 열었더니 "파일이 손상되어 열 수 없습니다" 창이 뜨는 상황, 다들 한 번쯤 겪어 보셨을 겁니다. 그런데 이 메시지가 뜨는 이유는 하나가 아닙니다. 진짜로 파일이 깨

richyeon.com

 

 

엑셀 조건부 서식 규칙이 수백 개로 쪼개지는 이유, 200번 복사 붙여넣기를 직접 재현 후기

[홈] 탭의 [조건부 서식] → [규칙 관리]를 눌렀다가 화면 가득 늘어선 규칙 목록을 보고 놀란 적 있으신가요. 셀 몇 개에만 색을 입힌 기억밖에 없는데, 목록에는 비슷한 규칙이 수십, 수백 개씩

richyeon.com