9비트 AES 키 사건

The case of the 9 bit AES key

v12.sh ▲ 128 댓글 68 ledoge

요약

AES-256을 내세운 여러 PDF 프로그램이 시각 값으로 키를 만들어 비밀번호 없이 풀렸습니다.

PDF의 AES-256 암호화는 무작위 32바이트 파일 키로 문서를 잠그고, 비밀번호로는 그 키만 감쌉니다. 보안 연구 회사 V12는 여러 구현에서 이 파일 키를 만드는 난수가 너무 허술해 키를 쉽게 추측할 수 있다고 밝혔습니다.

왜 중요한가

  • 비밀번호가 아무리 강해도 파일 키를 추측할 수 있으면 암호화는 사실상 없는 것과 같습니다.
  • 이미 배포된 암호화 PDF는 프로그램을 고쳐도 다시 보호할 수 없습니다.
  • 문제의 Foxit 코드가 2014년 PDFium 첫 공개 커밋에도 있어 다른 편집기로 퍼졌을 수 있습니다.

핵심 내용

  • MuPDF 1.28.5 이전 버전은 시각으로 시드한 drand48(시드가 같으면 같은 값을 내는 난수 함수)을 써서 가능한 키가 512개뿐이었습니다.
  • 최적화하지 않은 파이썬 코드로도 512개 후보를 모두 시험하는 데 약 11밀리초면 충분했습니다.
  • Foxit PDF Reader는 시각 값과 사실상 0인 바이트를 SHA-256으로 해시해 키를 만들고, 지금도 이 방식을 씁니다.
  • 연구진은 Foxit 방식으로 1970년 이후 모든 시각을 4.85초 만에 훑었습니다.
  • OpenPDF 3.0.5와 iText 9.7.1은 밀리초 시각과 JVM 여유 메모리를 시드로 써서 경우의 수는 많지만 256비트 보안에는 못 미칩니다.

HN 반응

  • 여러 이용자는 키 길이보다 암호학적으로 안전하지 않은 난수가 본질이라며, 운영체제가 주는 암호용 난수를 쓰라고 강조했습니다.
  • PDF 프로그램이 암호화를 직접 구현하는 것 자체가 문제라는 지적에, 일반 사용자에게는 비밀번호만 넣는 내장 암호화가 현실적이라는 반론이 나왔습니다.

댓글

30개 표시 · 전체 68개
  1. philsnow HN

    PDF 프로그램이 자체 암호화를 하는 건 정말 말이 안 된다고 생각해요. "암호를 직접 만들지 말라"는 이유(물론 그 이유도 맞지만)보다는, PDF 프로그램(라이브러리, 뷰어, qpdf 같은 범용 도구 등등)을 만드는 사람들이 좋은 암호화 UX를 이해하고 설계하는 데 (꼭) 뛰어나지는 않기 때문이에요.

    그리고 요즘 PDF로 민감한 정보를 많이 주고받는다는 건 알겠는데, 왜 PDF 파일 형식에 암호화가 내장돼 있어야 하죠? 민감한 정보는 이미지 파일, 워드 문서, zip 파일, html 등등등등에도 담겨 오가잖아요. 파일 한 종류의 암호화 UX를 쓸 만하게 만드는 데 들어가는 노력을 "모든 파일"에 적용하면, 생태계마다 제각각 새로 만들 필요가 없어요.

    이건 "고급" 자동차 제조사들이 자기네 소프트웨어를 직접 만들겠다고 고집하면서 애플 카플레이를 안 붙이는 것과 똑같아요. 그런 회사들은 진짜 형편없는 팟캐스트 앱을 만들거나, 아예 신경도 안 쓰고 2006년도처럼 블루투스로 팟캐스트를 들으라고 하겠죠.

  2. dingaling HN

    왜 PDF 파일 형식에 암호화가 내장돼 있어야 하죠?

    '일반 사용자' 중에 암호화·복호화를 쓸 줄 아는 사람이 거의 없기 때문입니다. 익숙한 파일을 보내면서 '이 비밀번호를 입력하세요'라고 하는 편이 훨씬 쉽습니다. openssl에 어떤 인자를 넘겨야 하는지 웹에서 찾아보게 하는 것보다요. 명령줄이요? 그게 뭔가요?

    얼마 전에 AES로 암호화된 파일을 받았는데, gnupg로도 openssl로도 보낸 사람이 어떤 모드와 키 설정을 썼는지 알아낼 수 없었습니다. 그래서 쓸모없는 데이터 덩어리가 되고 말았죠. 아주 안전하긴 합니다만...

  3. lmz HN

    보통은 암호화된 형식과 암호화되지 않은 형식이 메타데이터 처리의 일부를 재사용할 수 있기를 바랍니다("일반 파일과 똑같은데 데이터만 암호화된 것"). 예를 들어 zip 파일이 전체가 아니라 항목별로 암호화되는 것도 같은 이유입니다.

    파일 형식마다 사람들이 열어 보고 싶어 하는 데이터의 종류가 다르다 보니, 지금 같은 상황이 된 겁니다.

  4. otabdeveloper4 HN

    왜 PDF 파일 형식에 암호화가 내장돼 있어야 하죠?

    iOS와 안드로이드에서도 암호화된 문서를 열 수 있어야 하니까요.

  5. exabrial HN

    String.getBytes(UTF-8)는 스스로 발목을 잡는 아주 흔한 방법이에요.

    무조건 Base64로 인코딩/디코딩하세요!

  6. tptacek HN

    "1.28.5 이전 MuPDF 버전은 drand48 계열의 구현을 사용한다"라... 네, 그러면 사실상 제대로 된 암호화를 안 하고 있는 거죠. 키 공간이 몇 비트인지는 핵심이 아닙니다. 키가 애초에 암호학적으로 무작위가 아니라는 게 문제입니다.

  7. somat HN

    OpenBSD가 한 방법을 쓸 수도 있습니다. 전통적인 약한 의사난수 인터페이스를 전부 암호학적으로 안전한 것에 연결해 버리는 거죠. 그래도 drand48() 인터페이스와는 여전히 맞습니다. 그래도 보안이 필요한 곳에 이걸 쓰고 싶지는 않지만, 적어도 이제 rand()는 진짜 무작위입니다. http://man.openbsd.org/drand48

    또 하나 거슬리는 건, hash()를 써야 할 때 rand()를 쓰는 사람들입니다. 이 얘기는 다음에 따로 투덜대겠습니다.

  8. hansvm HN

    그 투덜거림이 궁금하네요(저희 회사에서는 거의 모든 곳에 hash()를 쓰기로 했거든요. 다른 관점도 듣고 싶어요).

  9. somat HN

    제 생각에 rand()(와 그 친척들)와 hash(thing)(과 그 친척들)은 거의 같은 함수입니다. 요구되는 특성도 아주 비슷하고, 가장 큰 차이는 rand()는 비결정적이고 hash()는 결정적이라는 점뿐입니다.

    워낙 비슷하다 보니 rand()를 "내부 상태 s = hash(s) 후 s 반환" 같은 식으로 만드는 일이 흔하고 실제로도 그렇게 합니다. 그러면 또 다른 사람들이 우연히 드러난 그 결정적 hash() 동작을 원해서 rand() 위에 말 그대로 세계 전체를 쌓아 올립니다.

    이 방식의 또 다른 문제는 rand()의 내부 구현이 불투명하고 알려져 있지 않으며, 명세를 어기지 않고도 바뀔 수 있다는 점입니다. 반면 hash()는 결정적이어야 하기 때문에 보통 안정적인 알고리즘이 공개돼 있습니다.

    구체적인 사례가 있습니다. 예전 직장에서 장기 보관하는 고객 주문 아카이브를 암호화해 두었는데, 키가 날짜의 해시였습니다. 이 자체도 좀 수상쩍지만, 아카이브는 오프라인으로 현장에 물리적으로 잠가 두고 있어서 그나마 괜찮았습니다. 진짜 문제는 암호화를 win98 머신에서 perl 스크립트로 했다는 점이었습니다. 스크립트는 사실상 "seed(date); key = rand(); encrypt(data, key)"였고, 나중에 데이터를 보고 싶으면 키를 다시 만들어 낼 수 있을 거라고 기대한 겁니다. 이걸 보고 "perl은 잘 모르지만 이건 안정적이지 않을 것 같은데" 싶어서 몇 가지 확인해 봤습니다. 아니나 다를까 rand()의 동작은 운영체제나 버전에 따라 달라질 수 있었습니다. 그러니 키가 그 win98 머신과 그 특정 perl 버전에 철저히 묶여 버린 거죠. 결국 그 머신으로 쓰인 키를 전부 만들어서 데이터베이스에 저장해 두고, 다른 머신들이 그걸로 아카이브를 복호화하게 한 것 같습니다.

  10. lo0dot0 HN

    날짜를 키로 암호화하면 가능성이 높은 날짜를 하나씩 대입해서 깰 수 있습니다. 밀리초 단위 시간까지 넣었나요, 아니면 날짜만 넣었나요? 그게 중요한지는 잘 모르겠지만요.

  11. aidenn0 HN

    링크하신 매뉴얼 페이지를 보면, OpenBSD의 동작은 drand48() 인터페이스와 맞지 않습니다. drand48() 인터페이스는 결정성을 요구하니까요.

  12. NelsonMinar HN

    우리 소프트웨어 엔지니어들은 대체 뭐가 문제라서 이런 정말 어이없고 기초적인 실수를 계속 저지를까요? 가끔은 프로그래밍도 면허를 받고 정기적으로 시험을 봐야 하는 게 아닌가 싶어요.

  13. anonymous908213 HN

    보안이나 신뢰성이 핵심인 시스템을 다루려면 면허가 필요한 엔지니어링 분야와, 의존성이 1000개나 되는 JS 프론트엔드를 마음껏 주무르며 놀아도 되는 면허 없는 일반 소프트웨어 개발 분야로 나눠야 합니다. 절실해요. 이 둘은 섞이면 안 되는데도 너무 쉽게 섞여 버립니다.

  14. greggsy HN

    엔지니어 자격증은 이미 있고, 여러 산업과 정부가 플랫폼이나 소프트웨어를 사용 승인하기 전에 자체 인증 제도를 적용합니다.

    신뢰 수준은 제각각이고요. 결과가 늘 완벽하진 않지만, 애초에 그게 목적은 아닙니다.

  15. nyargh HN

    자격 중심주의는 해결책이 아닙니다. 그것도 결국 편법의 대상이 될 겁니다. 인도의 학위 공장이나 대형 IT 컨설팅 업체가 해마다 "자격을 갖춘" 엔지니어를 수천 명씩 찍어 내고 있잖아요.

    제 몫을 하는 채용 담당자라면 자격증이 이력서에 빼곡한데도 완전히 무능한 지원자를 적어도 한 번쯤은 걸러 낸 적이 있을 겁니다.

  16. GoblinSlayer HN

    인증은 좀 다를 수도 있지 않을까요? 인증받은 Electron 엔지니어라면 앱을 만드는 데 노력을 하나도 안 들이는 방법을 다룬 튜토리얼을 읽는 게 전부일지도 모르죠.

  17. asveikau HN

    암호화 구현의 문제점 하나는 엉터리 구현이 겉으로 보기에는 제대로 된 구현과 구분이 안 된다는 겁니다. 완전히 망가진 암호화도 겉보기에는 멀쩡히 작동하는 것처럼 보이고, 대부분의 사람은 깊이 들여다보지 않습니다. 이건 수년 전부터 계속 지적돼 온 얘기입니다.

  18. LeoPanthera HN

    이게 제가 AI가 만든 슬롭 코드를 별로 걱정하지 않는 이유 중 하나예요.

    사람의 수준이 그렇게 높지 않거든요.

    저는 코드의 출처를 따져서 거르는 것보다 엄격한 테스트를 하는 쪽이 훨씬 좋아요.

  19. nyargh HN

    사람이라면 테스트가 그렇게까지 엄격할 필요도 없습니다. 15분만 대화해 보면 자기 경험의 깊이를 부풀리는 사람은 쉽게 가려낼 수 있으니까요.

    하지만 AI는 그게 불가능할 겁니다.

    코드 테스트를 말씀하시는 거라면, "테스트는 버그의 존재를 보여 줄 수 있을 뿐, 버그가 없음을 보여 줄 수는 없다"는 말도 있죠.

  20. hansvm HN

    AI를 쓰면서 엄격한 테스트를 구현하는 방법은 뭔가요?

  21. jburgess777 HN

    DMCA는 키를 알아내기가 아무리 쉬워도 암호화된 콘텐츠에 접근하는 걸 여전히 불법으로 보나요? https://www.law.cornell.edu/uscode/text/17/1201

    새로운 LLM 모델 소유 업체들이 이 조항을 무효로 만들고 싶어 할까요, 아니면 제한 없는 모델이 얼마나 위험한지 보여 주는 데 이용하고 싶어 할까요?

  22. nextaccountic HN

    약한 암호화는 암호화가 없는 것과 같다는 주장도 충분히 성립할 수 있어요.

  23. leni536 HN

    Pdfium이 Chrome/Chromium의 PDF 뷰어를 구동하긴 하는데, 어쩌면 Chrome은 PDF 문서 암호화를 기능으로 제공하지 않아서 영향을 안 받는 걸까요?

  24. ubutler HN

    직접 RNG를 만들 때의 규칙 1번은 만들지 말라는 겁니다.

    규칙 2번이요? 제발 만들지 마세요.

  25. Mikhail_Edoshin HN

    그 말은 결국 "어떤 권위를 믿어라"라는 뜻이고, 그것도 하나의 일입니다. 게다가 이미 만들어진 해결책이 딱 맞지 않을 때, 예를 들어 덩치 큰 라이브러리를 끌어와야 할 때는 통하지 않죠. 진짜 답은 "소프트웨어 공학 교재와 RNG의 표준 참고서를 활용하라"가 되어야 합니다. 문제는 그런 참고서가 없다는 거예요.

  26. mik1998 HN

    Handbook of Applied Cryptography는 고전적인 암호 알고리즘을 구현할 때 참고하기 좋은 자료입니다.

  27. j16sdiz HN

    그래서 시스템 RNG를 쓰는 거죠!

  28. cowlevel HN

    rand(3)가 아니라 암호학적으로 안전한 것을 써야 하니 조심하세요.

    시스템 관리자라면 VM이나 임베디드 장치에서 키를 만들 때 각별히 조심하세요. 이런 환경은 엔트로피 소스를 과대평가하는 경향이 있어서, VM을 복제할 때마다 똑같은 키가 만들어질 수도 있습니다. 경우에 따라서는(콜록 ECDSA) 서로 다른 두 메시지에 서명하면서 같은 키와 같은 논스를 쓰면 치명적입니다. 개인 키가 곧바로 새어 나가거든요.

  29. saidnooneever HN

    VM 얘기는 좋은 지적이네요. VPS를 쓴다면 제공업체가 형편없는 RNG를 끼워 넣고 제대로 된 하드웨어 RNG에는 접근하지 못하게 할 수도 있잖아요. 알아내려면 정말 파고들어야 할 거예요 :/

    -object rng-random,id=objrng0,filename=/dev/null

    아니면 그냥 4가 들어 있는 파일일 수도 있고요 :O

  30. Novosell HN

    그 4가 무작위이기만 하다면야!

Hacker News에서 보기 ↗