공개 웹에는 만료되지 않은 인증서가 수억 개 있고, 그중 일부는 폐기됐다 — 키가 유출됐거나, 도메인 주인이 바뀌었거나, CA가 오발급을 잡아냈거나. 폐기된 것들의 목록은 브라우저가 HTTPS 연결마다 물어야 하는 질문의 답이다: 이 인증서 아직 유효한가?

20년 동안 이 질문은 형편없이 답해졌다. 전체 폐기 목록은 배포하기엔 너무 커서, 브라우저는 CA에게 인증서 하나씩 OCSP로 물었다 — 이건 당신의 방문 기록을 제3자에게 흘렸고, 더 나쁘게는 공격자가 그 조회를 막는 순간 조용히 통과(fail-open)해 버렸다. 2025년 8월 Let’s Encrypt는 OCSP 응답 서버를 완전히 껐고, 거의 아무것도 깨지지 않았다. 그 확인은 이미 몇 년째 허울이었으니까.

그래서 놀라운 대목은 이것이다. 2025년 4월 1일 출시돼 모든 데스크톱 사용자에게 기본으로 켜진 Firefox 137부터, 브라우저는 다들 불가능하다던 일을 한다: 웹 전체의 폐기 목록을 내려받아 로컬에서, 네트워크 왕복 없이, 아무에게도 아무것도 드러내지 않고 인증서를 대조한다. WebPKI의 모든 폐기 목록 전체가 수 메가바이트에 들어간다. 이게 CRLite이고, 이게 작동하는 이유는 대략 맞는 걸로 유명한 자료구조를 정확히 맞게 바꿔놓는, 진짜로 영리한 엔지니어링이다.

“그냥 목록을 내려받으면” 언제나 답이었고, 언제나 실패했던 이유

최초의 폐기 방식인 인증서 폐기 목록(CRL)이 바로 이것이었다: CA가 폐기한 시리얼 번호를 전부 담은 서명 파일을 게시하고, 클라이언트가 그걸 내려받는다. 정직한 설계다. 문제는 크기였다 — CRL은 커지고 낡았고, 클라이언트는 연결마다 CA별로 메가바이트짜리 시리얼 목록을 당기고 싶어하지 않았다. 그래서 업계는 한 번에 하나씩 묻는 OCSP 모델로 흘러갔다. 크기 문제를 프라이버시 문제와 fail-open 문제로 맞바꿨고, 둘 다 원래 문제보다 나빴다.

CRLite는 원래 아이디어로 — 목록 전체를 배포한다 — 돌아가되, 크기 문제를 문제가 아니게 될 만큼 강하게 눌러버린다. 순진하게 만든 전체 목록은 수백 메가바이트다. Mozilla의 2020년 글은 약 300MB의 폐기 데이터를 약 1MB에 담았다. 지금 Firefox 클라이언트는 하루 평균 약 300kB의 폐기 데이터를 당긴다: 45일마다 수 메가바이트짜리 새 스냅샷, 그 사이사이 작은 델타 업데이트, 그리고 로컬 필터는 12시간마다 갱신된다. 공개 웹의 폐기 상태 전체를, 최신으로 유지하면서, 웹페이지 한 장보다 적은 대역폭으로.

어떻게 거기 도달할까? 평범한 압축으로는 안 된다. 인증서를 아예 저장할 필요가 없다는 걸 깨달으면 도달한다 — 인증서당 딱 한 비트만 답하면 된다: 폐기됨, 또는 아님.

블룸 필터, 그리고 그것의 문제

블룸 필터는 “이게 집합에 있나?”를 거의 공간 없이 답하는 고전 자료구조다. 항목을 해시해 비트 배열의 몇 비트를 켜고, 멤버십을 확인하려면 그 비트들이 켜져 있는지 본다. 작고 빠르다. 모든 교과서가 경고하는 함정은, 이게 **거짓 양성(false positive)**을 낼 수 있다는 것이다: 집합에 없는 것을 가끔 “있다”고 말한다. 거짓 음성은 절대 내지 않지만(“없다”고 하면 확실하다), 거짓 양성률이 압축의 대가다.

폐기에서 거짓 양성은 재앙이다. 필터가 유효한 인증서를 폐기됐다고 잘못 말하면, 브라우저는 멀쩡한 사이트를 거부하고, 사용자는 아무 잘못 없는 은행에서 보안 오류를 본다. 멀쩡한 사이트를 이따금 무작위로 깨는 폐기 시스템은 시스템이 없느니만 못하다. 그래서 순수 블룸 필터는, 그 우아함에도 불구하고, 정확히 잘못된 도구처럼 보인다: 근사적인데, 폐기는 확실성을 요구한다.

이걸 작동하게 만드는 수가 여기 있다.

닫힌 세계 트릭: 자기 오류를 스스로 상쇄하는 캐스케이드

CRLite에는 대부분의 블룸 필터 응용에 없는 이점이 있다: 인증서의 전체 우주를 안다. 공개 신뢰 인증서라면 반드시 제출돼야 하는 공개·추가 전용 로그인 Certificate Transparency 덕분에, Mozilla는 폐기된 것만이 아니라 웹의 사실상 모든 유효 인증서를 열거할 수 있다. 두 집합을 다 안다: 존재하는 전부, 그리고 폐기된 전부.

두 집합을 미리 알면, 필터를 만든 다음 배포하기 전에 현실과 대조해 감사할 수 있다.

  1. 폐기된 인증서 전부에 대해 블룸 필터를 만든다. 진짜 폐기된 건 전부 “폐기”라고 답하고(거짓 음성 없음), 거기에 거짓 양성 몇 개 — 잘못 표시된 유효 인증서 한 줌 — 가 붙는다.
  2. 유효 인증서 전체 목록이 있으니, 정확히 어떤 유효 인증서가 거짓 양성이 됐는지 찾을 수 있다. 그것들만으로 두 번째 필터를 만든다 — 멤버가 “첫 필터가 틀린 유효 인증서”인 필터.
  3. 그 두 번째 필터도 자기 거짓 양성이 있는데, 이번엔 폐기 집합에서 나온다. 그래서 그것들로 세 번째 필터를 만든다. 그런 식으로 이어진다.

각 층이 바로 윗층의 실수를, 점점 작아지는 집합에 대해 잡아내므로, 층은 빠르게 줄어든다 — 보통 캐스케이드는 몇 층 깊이뿐이다. 런타임에 인증서를 확인하려면 층을 따라 내려가고, 멤버십을 주장하는 마지막 층이 답을 정한다. 캐스케이드가 완전하고 알려진 우주에 대해 만들어졌기 때문에, 만들 당시 존재하던 모든 인증서에 대해 거짓 양성 0, 거짓 음성 0을 낸다. 확률적 자료구조가 정확한 답을 낸다 — 문제가 닫힌 세계이기 때문이다. 이건 이미 지도 전체를 손에 쥐고 있을 때만 가능한 수인데, CA를 감사하려고 만든 시스템인 Certificate Transparency가 부수효과로 조용히 가능하게 해준 것이다.

곱씹을 만한 대목이 이거다. CT는 오발급된 인증서가 숨지 못하게 설계됐다. 10년 뒤, 바로 그 공개 원장이 브라우저가 모든 폐기 목록을 주머니에 넣고 다니게 한다. 한 보장을 위해 지은 인프라가, 계획에 없던 다른 보장의 토대가 된다.

실제로 배포된 건 이미 논문을 지나쳤다

2017년 학술 설계 — 노스이스턴대·메릴랜드대·듀크대 연구진이 낸 CRLite: A Scalable System for Pushing All TLS Revocations to All Browsers — 는 위의 다층 블룸 캐스케이드를 썼다. 2025년 Firefox가 실제로 배포하는 건 이미 그걸 지나쳤다. Mozilla는 Clubcard라 부르는 집합 멤버십 방식을 만들어 다층 블룸 캐스케이드를 분할된 2층 Ribbon 필터 캐스케이드로 대체했다 — Ribbon 필터는 블룸 필터의 더 공간 효율적인 신형 사촌이다. 바꾼 이유는 평범하고 시사적이다: 대역폭. 원래 설계의 델타 업데이트가 몇 시간마다 모든 사용자에게 밀어넣기엔 컸고, 그래서 인코딩을 다시 설계해 줄였다. 핵심 아이디어 — 알려진 우주에 대해 자기 거짓 양성을 상쇄하는 캐스케이드 — 는 살아남았고, 그 밑의 필터 원시 요소만 더 나은 것으로 갈아 끼웠다.

이게 여전히 규범이 아니라 예외인 이유

CRLite는 현재로선 Firefox만의 것이다. Chrome은 10여 년 전 다른 길로 갔다: 실시간 폐기 확인을 그만두고 CRLSet을 민다 — 구글이 편찬해 넣을 가치가 있다고 판단한 선별된 고가치 폐기 목록이다. CRLSet은 의도적으로 포괄적이지 않다 — 전체 지도가 아니라 짧은 목록이다. 그래서 웹을 지배하는 두 브라우저는 정반대 철학을 갖는다: Chrome은 중요하다고 판단한 폐기를, Firefox는 이제 그 전부를 배포한다.

그리고 업계의 세 번째 답, 조용히 이긴 답은, 질문 자체를 덜 중요하게 만드는 것이었다. 인증서 수명이 무너지고 있다 — 몇 년에서, 398일로, 지금 200일로, 2029년엔 47일로. 몇 주만 유효한 인증서는 누가 폐기를 확인하든 말든 유출된 키의 피해를 몇 주로 제한한다. 실용적 도박이다: “되돌리기(undo)“를 고치지 말고, 그게 적용되는 창을 실패가 아프지 않을 때까지 줄여라.

CRLite는 더 야심 찬 답이다 — 폐기가 늘 약속했지만 결코 지키지 못한 닫힌 세계 보장을 실제로 만들어낸다. 실제 의존성도 있다: CA가 쓸 만한 CRL을 계속 게시해야 하고, CT는 완전한 채로 유지돼야 하고, 누군가는 집계 파이프라인을 돌려야 한다. 하지만 처음으로, 정직한 설계 — 목록을 내려받아, 로컬에서 확인하고, 아무에게도 말하지 않는다 — 가 들어맞는 답이 됐다. 목록은 애초에 그렇게 크지 않았다. 우리가 접는 법을 몰랐을 뿐이다.