이 노트는 TLS 연결의 암호화 여부와 ‘상대가 누구인가’, ‘그 상대가 이 작업을 할 수 있는가’를 세 단계로 분리합니다. 인증서 체인과 접속 이름을 검증하는 기본 모델에서 출발해 mTLS 신원을 API 인가로 매핑하고, 인증서 교체·기존 연결·세션 재개·pinning 실패 때 가용성과 복구 신뢰를 함께 판단합니다.
TLS 암호화와 상대 신원 검증
클라이언트가 HTTPS 서버에 연결하면서 인증서 검증을 끄면 트래픽은 암호화될 수 있어도 의도한 상대인지 보장할 수 없습니다. TLS의 키 합의 성공과 서버 신원 검증은 함께 필요한 경계입니다. 일반적인 인증서 기반 HTTPS를 전제로, 접속하려던 이름과 신뢰 앵커를 기준으로 검증해야 합니다.
모든 TLS 연결이 매번 인증서를 보내는 것은 아닙니다. TLS 1.3의 PSK·세션 재개 같은 모드에서는 다른 인증 근거를 사용하므로, Certificate 메시지의 유무보다 그 연결이 어떤 자격으로 누구를 인증했는지를 설명해야 합니다.
신뢰 체인과 SAN·hostname 검증
| 검사 | 묻는 것 | 빠졌을 때 |
|---|---|---|
| 신뢰 체인 | 허용 trust store로 이어지는 유효한 체인인가 | 임의 발급자 신뢰 |
| SAN·hostname | 원래 접속할 이름을 위한 인증서인가 | 다른 사이트의 정상 인증서 수락 |
| 기간·알고리즘·용도 | 현재 시점과 서버 인증 용도로 적합한가 | 만료·부적절한 자격 허용 |
| API 인증·인가 | 요청 주체가 이 작업·테넌트에 허용되는가 | 암호화된 무권한 요청 허용 |
shop.example.com을 조회해 IP에 연결하더라도 신원 검증의 기대 이름은 원래 서비스 이름입니다. SNI는 서버가 어떤 인증서를 낼지 선택하는 힌트이며 hostname 검증을 대신하지 않습니다. 같은 IP에서 다른 SNI를 쓰면 다른 인증서가 나올 수 있습니다. 사설 CA는 필요한 클라이언트에 필요한 신뢰 루트만 배포하고 회전·제거까지 관리합니다.
인증서 철회 처리도 플랫폼·클라이언트 정책에 따라 달라집니다. CRL·OCSP 지원과 실패 처리·캐시를 확인하지 않고 철회가 모든 클라이언트에 즉시 강제된다고 말하지 않습니다. 짧은 수명은 노출 창을 줄일 수 있지만 유출 시 즉시 차단을 자동 제공하지 않습니다.
mTLS 서비스 신원 인증과 별도 인가
그림을 글로 읽기
- 클라이언트 인증서 검증: 신뢰 체인·허용 workload
- 검증된 서비스 신원
- API·행동·테넌트 인가: 사용자 대행 범위도 확인
- 허용된 변경만 실행
- 클라이언트 인증서 검증 → 검증된 서비스 신원: 정책 주체로 매핑
- 검증된 서비스 신원 → API·행동·테넌트 인가: 신원이지 포괄 권한 아님
- API·행동·테넌트 인가 → 허용된 변경만 실행: 최종 집행
주문 서비스의 인증서가 유효해도 관리자 계정 삭제를 허용할 이유는 없습니다. 인증서 식별자를 서비스 정책의 주체로 매핑하고 endpoint·작업·테넌트 범위를 제한합니다. 사용자를 대신하는 호출이면 서비스 신원과 최종 사용자 권한을 둘 다 확인합니다.
TLS를 프록시에서 종료하고 앱으로 client identity를 헤더로 전달한다면 외부 입력 헤더를 제거·재작성하고, 앱 직접 접근을 차단하거나 같은 신뢰 검증을 강제합니다. 일반 헤더 문자열은 그 자체로 인증된 신원이 아닙니다.
인증서 교체와 기존 연결·세션 재검사 범위
새 인증서를 모든 진입 경로에 배포해도 이미 열린 연결은 옛 핸드셰이크로 맺어져 있으므로 그 연결의 인증서가 자동으로 다시 검사되지는 않습니다. 세션 재개 ticket도 새 인증서를 매번 확인하지 않을 수 있습니다. 따라서 유출 대응은 새 연결에서 옛 자격을 막는 것만으로 끝나지 않고, 연결 수명·재인증·ticket 키와 수명·기존 세션 종료 정책을 함께 정해야 합니다.
정상 교체는 만료 전 구·신 경로의 호환성을 확인하며 진행할 수 있습니다. 긴급 유출 때는 가용성 손실을 감수하고 옛 신뢰를 제거해야 할 수 있습니다. 모든 LB·지역·앱 버전에서 실제 handshake와 이름 검증을 확인하고 인증서 파일 배포 성공만 완료로 보지 않습니다.
Pinning과 배포·복구 능력의 선택
특정 인증서나 공개키를 pin하면 일반 신뢰 루트가 허용하는 상대보다 범위를 좁힐 수 있습니다. 인증서 전체 pin과 공개키 pin은 갱신 시 바뀌는 범위가 다르므로 무엇을 고정하는지 명시합니다. 보통의 체인·hostname 검증을 없애는 무조건적 예외로 구현하지 않습니다.
정상 교체에서는 새 키 pin을 미리 포함한 앱을 배포하고 보급을 확인한 뒤 서버를 전환합니다. 안전하게 관리한 backup pin을 미리 준비하는 선택도 가능합니다. 그러나 수년간 업데이트하지 않은 앱은 새 pin을 모를 수 있습니다. 구 앱 종료·필수 업데이트·별도 신뢰된 복구 업데이트 경로 중 어떤 계약을 제공할지 제품 요구로 정해야 합니다.
pin 실패 시 일반 검증을 끄거나 동일한 실패 채널에서 받은 새 pin을 무조건 신뢰하면 공격자가 복구를 가장할 수 있습니다. 복구 설정은 독립적으로 인증된 업데이트 경로와 명확한 권한을 가져야 합니다. 옛 키가 유출됐다면 구 앱 호환성 때문에 그 키를 계속 허용하는 것이 어떤 침해 창을 남기는지 드러내야 합니다.
접속 경로별 TLS 거절 검증
테스트 CA와 합성 서버로 다른 이름·만료·중간 체인 누락·미신뢰 루트·다른 서비스 인증서를 시험합니다. 오류를 진단할 때 서버가 낸 체인뿐 아니라 클라이언트의 trust store 버전·SNI·기대 이름·프록시를 기록합니다. 비밀키는 로그에 남기지 않습니다.
pin 교체는 새 앱·구 앱·backup pin·오프라인이었다가 복귀한 앱을 나눠 검증합니다. 기존 연결과 새 연결·재개 연결의 차이도 측정해야 합니다. 이 노트는 신뢰 설계이며 특정 TLS 제품이나 모바일 앱에서 실행한 실험 보고서는 아닙니다.
재현 연습은 합성 CA로 정상 인증서, 다른 SAN, 만료 인증서, 중간 인증서 누락, 미신뢰 루트를 각각 제공하고 클라이언트가 기대한 hostname과 trust store를 기록하는 것입니다. 예상 결과는 키 합의가 이루어져도 이름·체인 검증이 실패하면 연결을 허용하지 않는 것이며, mTLS 인증서가 유효해도 API 정책에서 허용하지 않은 tenant 작업은 거절하는 것입니다. pin 교체에서는 새 앱·구 앱·오프라인 복귀 앱·기존 연결을 분리해, pin을 모르는 구 앱의 복구 경로가 독립적으로 인증되지 않으면 안전한 업데이트가 아니라 신뢰 우회가 된다는 점을 확인합니다.