요약

  • TLS 세션 티켓은 서버가 재개 가능한 암호화 상태를 불투명한 객체로 봉인해 클라이언트가 보관하게 한다. 클라이언트는 상태를 지니고 있지만 내용을 해석하거나 서버가 이를 수용하도록 강제할 수 없다.
  • 클라이언트별 기록을 없앤 결과 남은 것은 더 작지만 더 중대한 서버 상태였다. 티켓 보호 키, 수명 정책, 그리고 플릿 수용 범위가 그것이다. 따라서 키 순환, 티켓 거부, 전체 핸드셰이크 폴백은 메커니즘의 일부였지 운영상의 사후 고려가 아니었다.

서버의 기억을 담은 봉인된 봉투

클라이언트는 봉인된 봉투를 들고 TLS 서버로 돌아온다. 그 봉투는 이전 연결에서 서버가 만든 것이다. 그 안에는 이전 세션을 재구성하는 데 필요한 재료가 들어 있다. 클라이언트는 봉투를 저장하고는 있지만 내용을 읽거나 만료를 고치거나 서버가 이를 존중하게 만들 수 없다. 봉인이 유효한지, 기억된 세션이 여전히 수용 가능한지는 오직 서버만 안다.

바로 이 드문 방식의 할당이 2006년 5월RFC 4507로 명시되었다. 다수의 사용자를 다루는 서버는 상태를 티켓으로 감싸 클라이언트에 넘겨줌으로써 사용자마다 별도의 세션 기록을 두지 않아도 되었다. 2008년 1월의RFC 5077은 첫 사양을 대체하면서 더 강한 권장 구성으로 같은 아키텍처를 유지했다.

이 최적화는 흔히 스테이트리스 재개(stateless resumption)라고 불린다. 이 이름은 그 경계가 여전히 보일 때만 유용하다. 세션별 저장소는 서버 밖으로 나갈 수 있었다. 그러나 티켓 보호 키, 검증 코드, 수명 정책, 현재 연결 상태, 그리고 재개 여부의 판단은 나가지 않았다.

TLS 세션 ID가 서버에게 요구한 기억

TLS는 이미 협상된 세션을 재사용할 수 있었다. TLS 1.2 사양인RFC 5246은 세션을 여러 연결이 암호화 매개변수를 공유할 수 있는 연관 관계로 기술했다. 서버가 선택한 세션 식별자는 활성 또는 재개 가능한 세션 상태를 가리켰다. 그 식별자가 돌아오고 서버가 여전히 상태를 지니고 있다면, 양측은 전체 협상을 반복하지 않아도 되었다.

이는 공개키 연산과 왕복 지연을 절약했지만, 식별자는 조회용 핸들에 불과했다. 대규모 서비스는 대응하는 기록을 가용 상태로 유지하고, 노화시키고, 치명적 실패 후 삭제하고, 다음 연결을 받게 될 어떤 서버에서든 찾아내야 했다. 부하 분산은 기억을 조율 문제로 바꾸었다. 클라이언트가 올바른 노드로 돌아오든, 아니면 세션 캐시가 클라이언트를 따라가든 둘 중 하나였다.

티켓은 이 조회를 뒤집었다. 클라이언트는 서버 메모리를 가리키는 짧은 이름 대신, 서버가 상태를 다시 조립할 수 있는 암호화로 보호된 꾸러미를 돌려준다. 이 객체는 부하 분산기를 통과할 수 있었다. 수용하는 노드에 필요한 것은 클라이언트별 데이터베이스 행이 아니라 올바른 보호 키였기 때문이다.

읽지도 못하고 승인하지도 못하는 운반자

RFC 5077은 티켓을 클라이언트에게 불투명한 것으로 다루었다. 권장 형식은 키 이름, 초기화 값, 무결성 검사 뒤에 암호화된 상태를 두었다. 상태에는 암호 스위트, 마스터 시크릿, 타임스탬프, 그리고 관련 클라이언트 인증 정보가 포함될 수 있었다. 기밀성이 이 내용을 가리고, 무결성 보호가 운반자가 수명이나 신원이나 권한을 몰래 바꾸지 못하게 막았다.

그럼에도 클라이언트는 단순한 임의의 블롭 이상을 지녔다. TLS 1.2 설계 하에서 클라이언트는 티켓과 함께 대응하는 마스터 시크릿과 매개변수를 캐시했다. 돌아온 서버는 티켓을 복호화·검증하고 상태를 재구성한 뒤, 핸드셰이크의 Finished 메시지로 양측이 필요한 시크릿을 실제로 지니고 있음을 확정했다. 대응하는 시크릿 없이 복사된 티켓은 완전한 재개 자격 증명이 아니었다.

이 구분이 중요하다. 소유는 클라이언트에게 연속성을 요청할 기회를 준 것일 뿐, 티켓의 의미를 정의할 권한을 준 것이 아니며, 암호학적 연속성을 현재의 애플리케이션 권한으로 바꿔주지도 않았다. 이전 TLS 세션 이후에 계정이 비활성화되었거나, 역할이 회수되었거나, 거래가 완료되었을 수 있다. 이런 것들은 티켓 위의 애플리케이션 결정이다.

거부가 일상으로 남아야 했던 이유

RFC 5077 티켓을 수용할 수 없거나 수용하고 싶지 않은 서버는 전체 핸드셰이크를 수행할 수 있었다. 이 폴백 덕분에 성능 힌트가 영구 의존으로 굳어지지 않았다. 재시작, 키 순환, 정책 변경, 다른 서빙 그룹으로의 라우팅은 서비스를 접근 불가로 만들지 않고도 오래된 티켓을 쓸모없게 만들 수 있었다.

클라이언트 역시 티켓을 보냈다는 사실로 성공을 추정하는 것이 아니라, 핸드셰이크를 통해 수용과 폴백을 구분해야 했다. 불투명한 객체는 형식상 완전하면서도 만료되었거나, 알 수 없는 키로 발행되었거나, 현재 정책상 수용 불가일 수 있다. 거부는 어떤 최적화를 재사용할 수 없다는 말이지, 그 자체로 상대의 신원이 거짓이라는 말이 아니다.

갱신에도 비슷한 경계가 있었다. 서버는 재개된 교환 중에 새 티켓을 발급할 수 있었지만, 핸드셰이크가 완료되기 전까지는 클라이언트가 그것을 받아 채택했다고 가정할 수 없었다. 전달, 수용, 이후의 사용은 별개의 사건으로 남았다.

작은 키 집합이 지닌 큰 폭발 반경

스테이트리스화는 저장된 위험의 형태를 바꾸었다. 수백만 개의 클라이언트 기록이 훨씬 작은 티켓 키 집합으로 대체될 수 있었지만, 그 키들은 많은 티켓의 보호된 상태를 열어줄 수 있었다. 더 작은 재고가 자동으로 더 작은 결과를 뜻하지는 않았다.

RFC 5077은 티켓 키를 안전하게 생성하고, 티켓 보호에만 사용하며, 정기적으로 교체할 것을 권했다. 완전한 키 관리 설계는 프로토콜 밖으로 남겨두었다. 이 생략은 주제를 무시해도 된다는 허가가 아니라, 단일 서버와 클러스터와 다중 리전 플릿이 서로 다른 수용 경계를 가진다는 인정이었다.

하나의 키를 공유하면 어떤 노드든 다른 노드가 발행한 티켓을 재개할 수 있어 부하 분산이 단순해진다. 동시에 그 키를 지닌 모든 주체가 같은 침해 도메인에 속하게 된다. 키를 국지적으로 유지하면 이 도메인은 줄어들지만, 클라이언트가 다른 곳에 도착했을 때 전체 핸드셰이크 폴백이 늘어난다. 성능 이점과 보안 경계는 같은 선택의 두 가지 시점이다.

만료, 순환, 그리고 수명 힌트의 한계

RFC 5077에서 서버는 수명 힌트를 제공했다. 클라이언트는 만료된 상태를 삭제하도록 기대되었고 더 일찍 삭제할 수도 있었으며, 서버는 힌트보다 짧게 또는 길게 티켓을 수용할 수 있었다. 그 숫자는 저장 지침이지 미래 서비스의 예약이 아니었다.

RFC 9325의 현재 운영 지침은 주변 키에 대해 더 단호하다. 티켓 암호화 키는 정기적으로 교체해야 하고, 오래된 키는 유효 기간 이후 반드시 폐기해야 하며, 티켓 수명은 합리적으로 유지해야 한다. 그렇지 않으면 보관된 하나의 키가 침해되었을 때 재개 가능한 역사 전반에 미치고, 원래 핸드셰이크에서 선택된 순방향 기밀성(forward secrecy) 속성을 훼손할 수 있다.

따라서 만료에는 적어도 세 개의 시계가 있다. 클라이언트에게 알려진 수명, 서버가 현재 수용하는 범위, 그리고 보호 키가 복구 가능한 기간이 그것이다. 그중 하나를 전체 수명 주기로 다루면 잘못된 확신이 생긴다.

재개된 시크릿이 더 강한 역사가 필요했을 때

재개는 그것이 재개하는 세션의 보안성을 물려받는다.RFC 7627은 오래된 TLS의 약점을 드러냈다. 마스터 시크릿이 핸드셰이크 맥락을 충분히 반영하지 않았던 것이다. 능동적 공격자는 세션들 사이에서 시크릿을 동기화할 수 있었고, 세션 재개를 포함해 그 고유성에 의존하던 메커니즘을 무너뜨릴 수 있었다.

확장 마스터 시크릿(extended master secret) 수리는 시크릿을 핸드셰이크 트랜스크립트의 해시에서 도출했다. 여기서의 역사적 교훈은 하나의 확장보다 넓다. 휴대 가능한 봉인된 상태는, 봉인되기 전에 상태에 결합된 증거만큼만 신뢰할 수 있다. 컨테이너를 보호하는 것으로 모호한 기원을 수리할 수는 없다.

TLS 1.3은 티켓을 PSK 식별자로 바꾸었다

RFC 8446은 핸드셰이크를 다시 설계하면서 티켓을 재개 사전 공유 키(resumption PSK)의 식별자로 기술했다. 서버는 본 핸드셰이크 이후NewSessionTicket을 보낸다. 이 메시지는 수명, 나이 난독화 값, 논스, 그리고 불투명한 티켓을 담는다. 이후 ClientHello는 그 식별자와, 대응하는 PSK를 지니고 있음을 증명하는 바인더를 제시한다.

TLS 1.3은 광고되는 티켓 수명을 7일로 제한하며, 클라이언트는 그보다 오래 캐시할 수 없다. 재개 PSK를 새로운 임시 디피–헬만 교환과 결합할 수도 있다. 재개된 연결에서 순방향 기밀성을 원하는 배포에 대해 RFC 9325는 이 모드를 권장한다. 재개가 곧 오래된 키 자료를 영원히 재생하는 것을 뜻하지는 않는다.

TLS 1.3은 조기 데이터(early data)도 허용하지만, 이는 인접한 선택적 결정이다. 0-RTT가 비활성화된 상태에서도 티켓은 보통의 재개 핸드셰이크를 가속할 수 있다. 모든 티켓이 일회용이라는 주장에 애플리케이션 재사용 위험을 몰래 끼워 넣어서는 안 되며, 조기 데이터를 비활성화한다고 해서 재개 키 관리의 필요가 사라지지도 않는다.

프라이버시는 암호문 안에서 사라지지 않았다

티켓 내용을 암호화하면 관찰자가 전달된 세션 상태를 읽을 수 없다. 그러나 반복적인 제시가 관찰 불가능해지지는 않는다. RFC 5077은 같은 티켓의 재사용이 경로상 관찰자가 여러 핸드셰이크를 상호 연관시키게 할 수 있다고 경고했다. RFC 9325 역시 세션 재개가 추적을 가능하게 할 수 있음을 밝힌다.

따라서 프라이버시는 티켓 내부가 암호화되어 있는지만이 아니라, 발행 빈도, 재사용 정책, 수명, 그리고 티켓 주변에 여전히 보이는 것에 달려 있다. 어떤 객체는 자신의 의미를 숨기면서도 안정적인 레이블로 기능할 수 있다.

무엇이 움직였고, 무엇이 남았고, 티켓이 증명하지 못한 것

세션 티켓은 가치 있는 변환을 이루어냈다. 세션별 재구성 데이터를 필수적인 서버 측 조회에서 분리해, 유연한 서빙 토폴로지를 허용하고 반복되는 핸드셰이크 비용을 줄였다. 클라이언트가 객체를 들고 다니고, 서버는 키와 수용 결정을 유지하며, 애플리케이션은 재개된 연결이 무엇을 할 수 있는지에 대한 권한을 유지했다.

이 메커니즘은 사람의 신원을 증명하지 않았고, 현재의 권한 부여를 보장하지 않았고, 인쇄된 기한까지 수용을 약속하지 않았고, 모든 티켓을 일회용으로 만들지 않았고, 플릿을 절대적으로 스테이트리스로 만들지도 않았다. 그 오래된 교훈은 더 정확하다. 상태는 그것을 해석할 권리를 옮기지 않고도 옮겨질 수 있다. 봉인, 그 키, 그 수명, 그 공유 경계, 그리고 전체 핸드셰이크 출구가 모두 보일 때에만 시스템은 통제 가능하게 남는다.

출처와 근거의 한계

프로토콜 기록은RFC 4507,RFC 5077,RFC 5246,RFC 7627,RFC 8446및RFC 9325이다. 플릿 키와 운영 비용에 대한 분석은 이들 사양이 규정한 메커니즘과 권장 사항에서 도출한 추론이며, 특정 공급업체나 배포에 대한 측정이 아니다.