MuPDF는 AES-256 키를 9비트 난수로 만들고, Foxit은 타임스탬프 해시로 만든다
- MuPDF 1.28.5 이전 버전은 drand48 LCG를 time(NULL) 초 값으로 한 번만 시드해 AES-256 파일 키를 만드는데, 출력 바이트가 상태의 17~24비트에서만 나오고 하위 16비트는 0x330e로 고정돼 실제 키에 영향을 주는 타임스탬프 비트가 9비트뿐임
- 가능한 스트림이 512개뿐이라 최적화 없는 파이썬 전수 대입으로 약 11ms 만에 키가 나오고, 같은 LCG로 만든 /ID가 트레일러에 평문으로 남아 후보 검증에 쓰임
- Foxit PDF Reader 2026.1.3.36551은 파일 키를 SHA-256(uint32_le(time(NULL)) || 32바이트 미초기화 버퍼 || "there")로 유도하며, 미초기화 바이트는 실제로 0으로 채워져 무작위성을 전혀 더하지 않음
- /Perms 권한 블록에 알려진 평문이 있어 해시 한 번과 AES 블록 복호화 한 번으로 후보를 검증할 수 있고, 비밀번호 해싱이나 문서 복호화는 필요 없음
- PDF revision 6은 32바이트 랜덤 파일 키로 내용을 암호화하고 비밀번호와 솔트 해시로 그 키를 감싸는 구조인데, 랜덤 생성이 부실하면 비밀번호 없이 복호화되며 열람용 비밀번호로도 제한 없는 사본을 만들 수 있음
Hacker News opinions
예전에 하드웨어 지갑 엔트로피 부족했던 사건이랑 판박이네. 키는 256비트라고 광고하면서 실제 엔트로피는 9비트라니.
C로 만든 PDF 툴 쓰는 사람이 이상한 거 아님? 보안 사고 터지는 거 보면 언어부터 의심하게 됨.
진짜 궁금해서 묻는데 C가 왜 문제임? PDF 파서는 원래 C로 많이들 만드는데.
대안은 Rust나 Go 쓰면 되는 거 아닌가 싶은데, 실제로 PDF 렌더링 제대로 하는 라이브러리가 얼마나 있겠냐.
솔직히 언어 보고 툴 판단하는 사람 거의 없음. 이번 버그도 C라서 생긴 게 아니라 RNG를 대충 만든 사람 문제임.
RNG 직접 만드는 규칙 1번은 하지 마라임. 규칙 3번은 키 크기만큼 랜덤 비트를 써라, 이건 진짜 기본인데.
우린 시스템 RNG 쓰니까 괜찮다는 말 하려는 건데, MuPDF도 그랬으면 이 사고 안 났겠지.
핵심은 키 공간 비트 수가 아니라 애초에 암호학적으로 랜덤이 아니라는 점임. drand48로 키 만드는 순간 암호화가 아님.
OpenBSD가 rand() 계열 전부 CSPRNG로 묶어버린 게 생각나네. 인터페이스는 그대로 두고 속만 바꾼 거.
소프트웨어 엔지니어들은 왜 이런 기본 실수를 계속할까. 보안이 중요한 시스템은 라이선스 주고 정기 시험 봐야 한다고 봄.
그래서 나는 AI 슬롭코드 별로 안 무섭더라. 인간 기준선이 이 정도인데 뭐.
그건 소프트웨어 엔지니어가 아니라 그냥 코더임. 대학 교육 필요 없다고 하는 사람들 코드가 딱 이 꼴 남.
PDF 관련 코드는 그냥 방사능 취급하는 게 맞음. 관여 안 하는 게 정신건강에 이로움.
DMCA 1201은 키 찾기가 얼마나 쉬운지랑 상관없이 암호화된 콘텐츠 접근 자체를 불법으로 만드는데, 이 사례를 LLM 회사들이 어떻게 쓸지 궁금하네.