PDF 프로그램이 자체적으로 암호화를 구현하는 건 말이 안 됨. 암호 기술을 직접 만들지 말라는 원칙도 있지만, PDF 라이브러리·뷰어·qpdf 같은 도구를 만드는 개발자가 좋은 암호화 UX까지 이해하고 설계할 수 있는 건 아니기 때문임.
민감한 정보는 PDF뿐 아니라 이미지, 워드 문서, ZIP, HTML로도 오가는데, 굳이 파일 형식마다 암호화를 내장해야 할까? 한 형식의 암호화 UX를 개선할 노력을 모든 파일에 적용하면 생태계마다 다시 만들 필요가 없어짐.
고급 자동차 제조사가 Apple CarPlay를 통합하지 않고 자체 소프트웨어를 고집하는 것과 비슷함. 형편없는 팟캐스트 앱을 만들거나, 아예 만들지도 않고 2006년처럼 블루투스로 들으라고 하게 됨.
일반 사용자 중 암호화·복호화 방법을 아는 사람이 거의 없기 때문임. 익숙한 파일을 보내고 비밀번호를 입력하라고 하는 편이, openssl에 어떤 인수를 전달해야 하는지 검색하게 하는 것보다 훨씬 쉬움. 명령줄이 뭔지도 모르는 경우가 많음.
최근 AES로 암호화된 파일을 받았는데, gnupg도 openssl도 발신자가 쓴 모드와 키 설정을 알아내지 못해 쓸모없는 데이터 덩어리가 됨. 보안만큼은 아주 철저했음.
보통은 암호화 여부와 관계없이 메타데이터 처리를 재사용하려는 목적이 있음. 일반 파일과 똑같되 특정 데이터만 암호화하는 식이며, ZIP도 전체가 아니라 항목별로 암호화하는 이유가 여기에 있음.
암호화하지 않고 접근할 수 있어야 하는 데이터가 파일 형식마다 다르니 지금 같은 구조가 된 것임.
iOS와 Android에서도 암호화된 문서를 열 수 있게 하기 위해서임.
S/MIME은 어떨까?
“MuPDF 1.28.5 이전 버전은 drand48 계열 구현을 사용한다”면 사실상 제대로 된 암호화를 하지 않는 셈임. 핵심은 키 공간의 비트 수가 아니라, 키가 암호학적으로 안전한 난수로 생성되지 않는다는 데 있음.
OpenBSD처럼 기존의 취약한 의사 난수 인터페이스를 암호학적으로 안전한 난수 생성기에 연결할 수 있음. drand48() 인터페이스는 그대로 유지하면서 rand()도 안전한 난수를 반환하게 됨. 그래도 보안 용도로 이 인터페이스를 쓰고 싶지는 않음. http://man.openbsd.org/drand48.
hash()가 필요한 자리에 rand()를 쓰는 것도 못마땅하지만, 그 얘기는 다음으로 미루겠음.
소프트웨어 엔지니어들은 왜 이런 어처구니없는 기초적인 실수를 계속 반복할까? 프로그래밍에도 면허와 정기 시험이 필요하다는 생각이 가끔 듦.
보안·신뢰성이 중요한 시스템을 담당하는 면허 기반 공학 직군과, 의존성 1,000개짜리 JS 프런트엔드를 마음껏 다루는 일반 무면허 개발 직군을 반드시 구분해야 함. 둘을 혼동하면 안 되는데 너무 쉽게 뒤섞임.
암호 구현의 어려움 중 하나는 잘못된 구현도 겉보기에는 올바른 구현과 구별되지 않는다는 것임. 완전히 깨진 암호도 표면적으로는 정상 작동하는 것처럼 보이고, 대부분은 깊이 들여다보지 않음. 오래전부터 알려진 특성임.
AI가 만드는 저질 코드를 크게 걱정하지 않는 이유도 여기에 있음. 인간이 만든 코드의 수준도 그리 높지 않음. 코드의 출처로 거르는 것보다 엄격한 테스트를 훨씬 더 선호함.
이들은 “소프트웨어 엔지니어”가 아니라 코더임. 대학 교육이 프로그래밍에 아무런 도움이 되지 않는다고 말하기 좋아하는 부류임.
String.getBytes(UTF-8) 로 스스로 발목을 잡는 경우가 정말 흔함. 항상 Base64Encode/Decode를 써야 함!
Pdfium은 Chrome/Chromium의 PDF 뷰어에 쓰이지만, Chrome은 PDF 문서 암호화 기능을 노출하지 않아서 영향을 받지 않는 것 아닐까?
난수 생성기를 직접 구현할 때의 제1원칙은 직접 구현하지 않는 것임. 제2원칙도 제발 직접 구현하지 말라는 것임.
결국 “어떤 권위 있는 대상을 신뢰하라”는 뜻인데, 그것도 별도의 과제임. 기존 해결책이 거대한 라이브러리를 끌고 오는 등 요구에 잘 맞지 않으면 이 원칙은 통하지 않음.
진짜 답은 소프트웨어 공학 교과서와 난수 생성기의 표준 참고 문헌을 보라는 것이어야 함. 그런데 그런 표준 참고 문헌이 없음.
그래서 시스템 난수 생성기를 쓰는 것임!
제3원칙은 키 크기만큼의 무작위 비트를 사용하는 것임. 이를 지키지 못했다면 동기와 모든 고용주·고객 명단을 공개해야 함.
이런 어처구니없는 결함의 영향을 받는 PDF 구현체가 너무 많음. 정말 우연일까? 보이지 않는 손이 개입했을 가능성을 의심할 만한 정도임.