공개적으로 신뢰받는 TLS 인증서는 이제 모두 공개된 흔적을 남겨야 한다.

웹이 스스로에게 한 일 중 손꼽히게 잘한 일이다.

Certificate Transparency(인증서 투명성, CT) 이전에는 인증 기관(CA)이 내 도메인에 가짜 인증서를 발급해도, 누군가 그게 쓰이는 걸 우연히 보거나 CA가 털어놓지 않는 한 영영 모를 수 있었다. 공개 PKI 생태계 전체가 신뢰와 운의 묘한 조합에 기대고 있었다. CA가 몰래 잘못 발급하면 발견은 대개 우연이었다.

2011년, 공격자들이 네덜란드 인증 기관 DigiNotar에 침입해 500개가 넘는 가짜 인증서를 스스로 발급했다. 그중 하나가 google.com 와일드카드 인증서였다. 모든 브라우저가 믿는 CA가 서명했으니 기술적으로는 유효했고, 실제로 이란에서 Gmail 트래픽을 가로채는 데 쓰였다. 이게 들킨 건 Chrome이 구글 자신의 키를 고정(pinning)해 두고 있었기 때문이다. Chrome 사용자에게 오류가 떴고, 그중 한 명이 신고했다. 그 고정이 없었다면 아무도 몰랐을 가능성이 크다. DigiNotar는 모든 주요 브라우저에서 퇴출됐고 몇 주 만에 파산했다. (2013년에도 규모는 작지만 같은 일이 있었다. 프랑스 ANSSI 아래의 중간 인증서가 구글 인증서를 찍어 냈고, 이번에도 Chrome의 고정이 잡아냈다.)

뒤따른 질문은 뻔했다. 아무도 못 잡은 비인가 인증서는 얼마나 더 있을까? 불편한 답은 이랬다. 고정은 브라우저 업체가 굳이 챙겨 주는 몇 안 되는 사이트만 보호한다.

답: 전부 보이게 만든다

Certificate Transparency는 구글 엔지니어 벤 로리(Ben Laurie)와 애덤 랭리(Adam Langley)가 제안했고 2013년 RFC 6962로 나왔다. 발상은 단순하다. 인증서 발급은 모두 공개된 행위여야 한다.

실제로는 CA가 발급 직전에 “사전 인증서(precertificate)“를 CT 로그에 제출하고, 발급 뒤에 기록하는 방법도 있다. 로그는 공개돼 있다. 누구든 어떤 도메인이든 기록된 인증서를 전부 찾아볼 수 있다. 내가 허락하지 않은 인증서를 CA가 발급하면, CT가 그걸 알아내는 방법이다.

이 시스템은 부정 발급을 막지 않는다. 보이게 만든다. 이 차이가 중요하다. CT는 뚫린 CA가 가짜 인증서를 찍어 내는 걸 막지 못한다. 그 가짜가 숨지 못하게 할 뿐이다.

CT 로그는 어떻게 동작하나

CT 로그는 추가만 가능한 자료 구조, 정확히는 머클 트리다. 인증서를 넣을 수는 있어도 지우거나 고칠 수는 없다. 트리 구조 덕분에 어떤 인증서가 로그에 들어 있다는 것도, 로그가 변조되지 않았다는 것도 수학적으로 증명할 수 있다.

CA가 인증서를 제출하면 로그는 SCT(Signed Certificate Timestamp)를 돌려준다. 정해진 시간, 보통 24시간 안에 이 인증서를 로그에 넣겠다는 서명된 약속이다. 로그가 약속을 어기면 그 서명이 증거가 된다. SCT는 인증서 안에 들어가거나, TLS 확장이나 OCSP 스테이플링으로 전달된다.

브라우저가 SCT를 요구한다. Chrome은 2018년 4월 이후 발급된 인증서에 이를 요구해 왔고, Safari가 뒤따랐으며, Firefox는 2025년 초 135 버전부터 데스크톱에서 CT를 강제하기 시작했다. Chrome은 인증서 유효 기간에 따라 서로 다른 운영자의 로그에서 받은 SCT를 두세 개 요구한다. 없으면 거부된다. 이게 강제 장치다. 기록되지 않은 인증서는 브라우저가 믿지 않으니, CA는 기록을 건너뛸 수 없다.

독립된 로그는 여러 개이고 운영 주체도 다르다. Google, Cloudflare, Let’s Encrypt, Sectigo 등. 서로 다른 로그의 SCT를 여러 개 요구하니, 로그 운영자 한 곳이 어떤 인증서를 감출 수 없다.

무엇을 찾을 수 있나

브라우저가 기록되지 않은 인증서를 거부하므로, CT 로그에는 사실상 공개 CA가 웹용으로 발급한 모든 인증서가 들어 있다. 여기에는 이런 것이 포함된다.

  • 모든 서브도메인. CA가 internal.staging.corp.example.com에 인증서를 발급하면 그 이름이 CT 로그에 남는다. 내부 인프라에 공개 CA를 쓰는 도메인 소유자는 내부 이름 체계를 자기도 모르게 드러낸다.

  • 모든 발급자. 어느 CA가 언제 내 도메인에 인증서를 발급했는지 볼 수 있다. 처음 들어 보는 CA가 내 도메인 인증서를 발급했다면 경고 신호다.

  • 이력. CT 로그는 추가만 되므로 수년치 인증서 이력이 쌓여 있다. 언제 발급되고 언제 갱신됐는지, 시간에 따라 무엇이 바뀌었는지 추적할 수 있다.

그래서 CT는 보안 도구이면서 정찰 도구다. crt.sh 같은 서비스가 CT 로그 데이터를 무료로 검색하게 해 준다. 보안팀은 비인가 인증서를 감시하는 데 쓰고, 공격자는 정찰용 서브도메인을 찾는 데 쓴다.

이 이중 용도는 알려진 대가다. 보안 커뮤니티는 서브도메인이 드러나는 위험보다 가시성의 이득이 크다고 판단했다. 서브도메인 이름을 숨기는 데 보안이 걸려 있다면, 그건 다른 문제가 있다는 뜻이다.

프라이버시라는 대가

내부 호스트 이름이 CT 로그에 뜨는 건 일부 조직에겐 실제 걱정거리다. jenkins.internal.corp.example.com이나 vpn-staging.example.com 같은 이름은 전에는 안 보이던 인프라 정보를 드러낸다.

대처는 이런 식이다.

  • 내부용 인증서는 사설 CA로 발급한다. 사설 CA는 CT 로그에 제출하지 않는다. 내부 서비스가 공개 신뢰를 받을 필요가 없다면 공개 인증서도 필요 없다.
  • 대가를 받아들인다. 서브도메인 이름은 DNS 열거, 검색 엔진, 패시브 DNS 데이터베이스로도 흔히 드러난다. CT 로그는 출처를 하나 더할 뿐, 유일한 출처인 경우는 드물다.
  • 내부 인프라에 와일드카드 인증서를 쓴다. *.internal.example.com은 서브도메인별 인증서보다 덜 드러낸다. 와일드카드에는 와일드카드대로의 보안상 대가가 있지만.

감시: 도메인 소유자 대부분이 건너뛰는 부분

CT 로그 덕분에 도메인 소유자는 비인가 인증서를 감시할 수 있다. 누군가 내가 허락하지 않은 CA에서 내 도메인 인증서를 받으면 — 침해든, 사회공학이든, 도메인 검증의 허점이든 — 그 인증서가 CT 로그에 나타난다.

감시 서비스는 있다. Google, Facebook 같은 큰 조직은 자체 CT 감시를 돌린다. 작은 조직은 내 도메인에 새 인증서가 발급되면 알려 주는 무료 도구나 유료 서비스를 쓰면 된다.

그런데 도메인 소유자 대부분은 CT 로그를 전혀 감시하지 않는다. 그런 로그가 있는 줄도 모른다. crt.sh를 들어 본 적도 없다. 비인가 인증서를 잡을 도구는 바로 거기 있는데, 대부분은 집어 들지 않았다.

CT가 통한 이유

인터넷 전체를 바꾸려던 보안 개선이 숱하게 실패한 곳에서 CT가 성공한 건, 나중에 Let’s Encrypt가 유명하게 만든 것과 같은 수를 썼기 때문이다. 올바른 일을 자동으로 일어나게 만든다.

CA는 기록해야 한다. 브라우저는 SCT를 확인해야 한다. 도메인 소유자는 감시할 수 있지만 안 해도 된다. 강제는 그들이 관여하지 않아도 일어난다. 도메인 소유자 대부분이 CT 로그를 한 번도 안 봐도 시스템은 돌아간다.

좋은 설계다. 모두가 참여해야 하는 보안은 확장되지 않는다. 기본으로 작동하고, 원하는 사람만 감시를 더하는 보안이 실제로 배포된다.

CT가 신뢰 모델을 고친 건 아니다. 브라우저는 여전히 백 개가 훌쩍 넘는 루트 인증서를 믿는다. 그중 어느 CA든 어떤 도메인에든 인증서를 발급할 수 있다. 하지만 CT 덕분에 몰래는 못 한다. 신뢰 위에 세운 시스템에서 투명성은 검증 다음으로 좋은 것이다.