TLS 인증서 이름 불일치: 클라이언트는 어떤 이름을 비교하나 (RFC 9525)
TLS 클라이언트가 인증서의 SAN과 무엇을 비교하는지 RFC 9525 기준으로 정리합니다. 참조 식별자, DNS-ID와 IP-ID, Common Name 금지, 와일드카드 규칙, 불일치 처리와 점검 목록을 다룹니다.
브라우저나 HTTP 클라이언트가 “인증서 이름이 일치하지 않는다”며 연결을 끊을 때, 클라이언트는 두 가지를 맞대어 보고 있습니다. 하나는 클라이언트가 접속하려던 이름이나 주소이고, 다른 하나는 서버 인증서 안에 적힌 이름입니다. 이 비교 규칙을 정한 현행 IETF 문서가 RFC 9525 “Service Identity in TLS”입니다. 2023년 11월에 Proposed Standard로 발행되었고 RFC 6125를 대체(obsolete)합니다.
RFC 9525는 TLS뿐 아니라 DTLS, 그리고 TLS 핸드셰이크를 쓰는 QUIC 같은 프로토콜에도 적용되도록 쓰였습니다(§1.4.1). 이 글은 그중 HTTPS에서 자주 마주치는 경우를 중심으로 설명합니다.
참조 식별자와 제시 식별자
RFC 9525는 비교 대상을 두 가지 용어로 나눕니다(§1.5).
- 참조 식별자(reference identifier): 클라이언트가 기대하는 식별자입니다. 사용자가 입력한 URL, 미리 해 둔 설정, 웹 페이지의 링크처럼 클라이언트 쪽 입력에서 얻은 소스 도메인(source domain)과, 필요하면 애플리케이션 서비스 유형으로 만듭니다.
- 제시 식별자(presented identifier): 서버가 PKIX 인증서 안에 담아 보여 주는 식별자입니다. 인증서 하나에 여러 개가 들어 있을 수 있습니다.
핵심 규칙은 §6.1.1에 있습니다. 클라이언트는 받아들일 참조 식별자 목록을 만들어야 하고(MUST), 그 목록은 서버가 제시한 식별자와 독립적으로 만들어야 합니다(MUST). 인증서에 적힌 이름을 보고 “이 이름이면 되겠다”고 목록을 채우면 검증이 아무 의미가 없어지기 때문입니다.
DNS 해석 도중에 다른 도메인 이름을 거치게 되더라도, 애플리케이션이 그 중간 이름을 인증하는 절차를 따로 정의하지 않았다면 중간 이름은 참조 식별자가 아니며 참조 식별자로 취급해서는 안 됩니다(MUST NOT, §6.1.1). RFC는 이렇게 하면 DNS와 DNS 해석이 공격 표면에서 빠진다고 설명합니다. 이름 해석 과정 자체는 RFC 9525의 범위 밖입니다(§1.4.2). 해석 과정이 궁금하다면 DNS 이름 해석 글을 참고하세요.
비교 절차는 다음과 같습니다(§6, §6.2).
- 클라이언트가 소스 도메인(과 서비스 유형)으로 참조 식별자 목록을 만듭니다.
- 서버가 인증서로 제시 식별자를 보냅니다.
- 클라이언트가 참조 식별자마다 제시 식별자와 비교합니다. 하나라도 일치하면 성공이고 그 시점에 탐색을 멈춰야 합니다(SHOULD). 목록을 다 돌아도 일치가 없으면 실패입니다.
일치에 성공하면 클라이언트는 일치한 참조 식별자를 그 서비스의 검증된 신원으로 사용해야 합니다(MUST, §6.6).
HTTPS에서 쓰는 식별자: DNS-ID와 IP-ID
RFC 9525가 다루는 식별자는 모두 인증서의 subjectAltName(SAN) 확장 안에 들어갑니다(§1.5).
| 식별자 | SAN 항목 유형 | 쓰이는 곳 |
|---|---|---|
| DNS-ID | dNSName |
도메인 이름으로 접속할 때 |
| IP-ID | iPAddress |
IP 주소로 직접 접속할 때 |
| SRV-ID | otherName(SRVName) |
DNS SRV로 서비스를 찾는 프로토콜 |
| URI-ID | uniformResourceIdentifier |
인증서에 URI를 쓰도록 정한 프로토콜 |
SRV-ID와 URI-ID는 “어느 호스트인가”에 더해 “어떤 서비스인가”(예: IMAP, SIP)까지 묶는 식별자입니다. RFC는 XMPP와 SIP를 그런 예로 듭니다(§4.1). 반면 RFC 9525는 HTTP가 서버 인증서에서 URI 사용을 규정하지 않는다고 적고 있으며(§4.2), 일반적인 HTTPS에서는 DNS-ID와 IP-ID만 생각하면 됩니다.
RFC가 직접 든 예시는 다음과 같습니다(§6.1.2).
https://www.bigcompany.example/에 접속하는 브라우저의 참조 식별자는 DNS-IDwww.bigcompany.example하나입니다. 이때 인증서의 DNS-ID가web.bigcompany.example이면 거부됩니다.https://192.0.2.107/에 접속하면 IP-ID192.0.2.107하나,https://[2001:db8::abcd]에 접속하면 IP-ID2001:db8::abcd하나가 참조 식별자입니다.
Common Name은 쓰지 않는다
RFC 9525에서 인증서 subject의 Common Name(CN) RDN은 서비스를 식별하는 데 사용해서는 안 됩니다(MUST NOT, §2). 사실상 자유 형식 텍스트라 타입이 엄격하지 않고 해석이 모호하다는 것이 이유입니다. 같은 이유로 subjectName 안의 다른 RDN도 서비스 식별에 쓰면 안 됩니다(MUST NOT).
RFC 6125에서는 이를 CN-ID라고 불렀지만, RFC 9525의 변경 사항 목록(부록 A)은 서버 신원을 subjectAltName 확장으로만 표현할 수 있고 commonName을 쓰는 것은 더 이상 유효하지 않다고 명시합니다. 요약 절(§1.3)도 “도메인 이름처럼 보이는 문자열을 CN에 넣거나 검사하지 말라”고 정리합니다.
실무적으로 풀면(RFC 규칙에서 도출한 해석): CN에만 호스트 이름이 있고 SAN에 해당 DNS-ID가 없는 인증서는, RFC 9525를 따르는 클라이언트에서 이름 일치의 근거가 되지 못합니다.
DNS 이름 비교와 국제화 도메인
참조 식별자의 도메인이 국제화 도메인 이름(IDN)이 아니면, 레이블 단위로 대소문자를 구분하지 않는 ASCII 비교를 합니다(MUST, §6.3). 예를 들어 WWW.BigCompany.Example은 비교를 위해 www.bigcompany.example로 소문자화됩니다. 와일드카드 규칙(아래)을 제외하면 모든 레이블이 일치해야 합니다.
국제화 도메인은 다음 규칙을 따릅니다.
- DNS-ID 안에는 US-ASCII 범위 밖의 문자를 쓸 수 없고, 국제화 레이블은 A-label(
xn--로 시작하는 ASCII 형식)로 표현합니다(§2). - 참조 식별자에 U-label(유니코드 형식 레이블)이 있으면 클라이언트는 비교 전에 A-label로 바꿔야 하고(MUST), A-label끼리는 대소문자 구분 없는 ASCII로 비교합니다(MUST, §6.3).
- 매칭은 A-label로만 이루어지며, 비슷하게 보이는 문자 문제 같은 표시상의 혼동은 인증서 매칭이 아니라 애플리케이션 프로토콜과 사용자 인터페이스가 다룰 문제라고 RFC는 선을 긋습니다(§7.3).
A-label과 U-label 변환은 퓨니코드와 국제화 도메인 글에서 자세히 다룹니다.
또 하나 짚어 둘 점은, RFC 9525가 다루는 소스 도메인이 FQDN이라는 것입니다. 완전한 도메인 이름이 아닌 이름을 쓰는 것은 범위 밖이며 예상치 못하거나 정의되지 않은 동작으로 이어질 수 있다고 적혀 있습니다(§1.5).
와일드카드 규칙
RFC 9525에서 와일드카드는 인증서의 기본 기능으로 취급되지만(§1.3), 프로토콜 명세가 와일드카드를 금지할 수도 있습니다(§3). 와일드카드를 지원하는 경우 제시 식별자의 *는 다음 조건을 모두 만족해야 합니다(§6.3).
- 와일드카드 문자는 하나뿐이다.
- 와일드카드 문자는 가장 왼쪽 레이블의 전체 내용으로만 나타난다.
조건을 어기면 그 제시 식별자는 무효이며 무시해야 합니다(MUST). 또한 와일드카드는 참조 식별자의 레이블 하나에만 일치합니다. RFC는 이것이 한 레이블 이상에 일치할 수 있는 DNS 와일드카드와는 다른 규칙이라고 따로 밝혀 둡니다.
RFC 본문에 있는 예는 *.bigcompany.example은 허용되지만 *.*.bigcompany.example은 허용되지 않는다는 것입니다(§7.1). 아래 표의 나머지 행은 위 규칙을 적용해 이 글에서 만든 예시입니다.
| 인증서의 DNS-ID | 접속한 이름 | 결과 (규칙에서 도출한 예시) |
|---|---|---|
*.bigcompany.example |
www.bigcompany.example |
일치: *가 레이블 하나(www)에 대응 |
*.bigcompany.example |
a.b.bigcompany.example |
불일치: 와일드카드는 레이블 둘에 대응하지 않음 |
*.bigcompany.example |
bigcompany.example |
불일치: *에 대응할 레이블이 없음 |
w*.bigcompany.example |
www.bigcompany.example |
무시됨: *가 레이블 전체가 아님 |
www.*.example |
www.bigcompany.example |
무시됨: *가 가장 왼쪽 레이블이 아님 |
*.*.bigcompany.example |
a.b.bigcompany.example |
무시됨: 와일드카드가 둘 (RFC 예시) |
*.co.uk나 *.com처럼 공개 접미사(public suffix)를 덮는 와일드카드를 막는 일은 RFC 9525의 범위 밖입니다(§7.1). 와일드카드 인증서는 그 도메인 아래 단일 레이블 호스트 전부를 보증하므로, 의도하지 않은 호스트나 문제가 있는 호스트까지 보증할 위험이 있다는 점도 RFC가 지적합니다.
IP 주소로 직접 접속할 때
URL에 IP 주소를 직접 쓰면 참조 식별자는 IP-ID입니다(§6.1.1). 이 경우 규칙은 단순하고 엄격합니다.
- IP-ID 참조 식별자는 SAN의
iPAddress항목 값과 정확히 일치해야 하며, 네트워크 단위 같은 부분 일치는 없습니다(MUST, §6.2). - 비교는 참조 식별자의 바이트와
iPAddress항목의 바이트를 옥텟 단위로 맞대는 방식입니다(§6.4). IPv4는 4옥텟, IPv6는 16옥텟이며, 텍스트 표기를 이 값으로 바꿔야 할 수 있습니다(§2). - DNS 조회 결과로 얻은 IP 주소는 간접(indirect) 식별자이고, 간접 IP-ID 사용은 RFC 9525의 범위 밖입니다(§2).
RFC 9525는 역방향 DNS 조회를 직접 언급하지 않습니다. 다만 IP 주소가 참조 식별자이면 그것은 IP-ID이고(§6.1.1), DNS-ID 참조 식별자는 입력에 들어 있거나 입력에서 안전하게 도출된 FQDN, 또는 사용자 설정으로 소스 도메인에 명시적으로 연결된 FQDN으로 만든다고 규정합니다. 따라서(이 글의 해석) IP로 접속하면서 조회로 얻은 호스트 이름을 인증서의 DNS-ID와 비교하는 방식은 RFC 9525가 정한 절차가 아닙니다.
IP 접속에는 운영상 주의점도 있습니다. TLS SNI 확장은 도메인 이름만 전달하므로, IP-ID를 참조 식별자로 쓰는 클라이언트는 연결 시 서버에 그 정보를 알릴 수 없습니다. 그래서 IP-ID를 제시하려는 서버는 SNI 없이 들어온 연결에 그 인증서를 제시해야 합니다(§7.4).
또 IPv4 주소의 텍스트 표기는 형식상 유효한 DNS 이름이기도 합니다(§3). 시스템의 한 구성 요소는 값을 IP로, 다른 구성 요소는 FQDN으로 분류하면 보안 규칙이 어긋날 수 있으므로, 식별자 분류를 일관되게 유지하라고 RFC는 권고합니다(§7.4). §3은 URI 명세처럼 먼저 유효한 IPv4 주소인지 검사하는 방법을 예로 듭니다.
일치하지 않을 때의 처리
일치하는 제시 식별자를 못 찾았을 때의 동작은 클라이언트 종류에 따라 다릅니다(§6.6). 요구 수준(MUST/SHOULD/MAY)을 그대로 옮기면 다음과 같습니다.
자동화된 애플리케이션
- bad certificate 오류로 통신 시도를 종료하고 오류를 적절히 기록해야 합니다(SHOULD).
- 이 동작을 끄는 설정을 제공할 수 있지만(MAY), 기본값으로 꺼 두어서는 안 됩니다(MUST NOT).
사람이 직접 조작하는 클라이언트
- 사용자에게 신원 불일치를 알리고 bad certificate 오류로 통신 시도를 자동 종료해야 합니다(SHOULD).
- 고급 사용자에게 불일치를 무시하고 진행할 선택지를 줄 수 있습니다(MAY). RFC는 이 경우 극도로 신중해야 한다고 쓰고, 예로 먼저 중단을 권하고 그래도 진행하면 전체 인증 경로를 보게 하는 방식을 듭니다.
- 제시된 인증서를 이후 연결에서도 유효하다고 받아들이게 할 수 있습니다(MAY). 다만 이런 즉석 “고정(pinning)“이 이후 연결을 그 인증서 하나로만 제한해서는 안 되고(SHOULD NOT), 특정 상대에 특정 인증서를 정적으로 강제하는 정책은 실패한 연결 순간의 예외 처리가 아니라 사전 설정으로만 제공해야 합니다(SHOULD).
정리하면, 연결 종료는 RFC 9525에서 SHOULD 수준의 기본 동작이고, 불일치 검사를 기본값으로 끄지 말라는 것은 자동화 클라이언트에 대한 MUST NOT입니다.
구현·설정 점검 목록
아래 항목은 RFC 9525의 규칙을 실무 점검 형태로 옮긴 것입니다. 특정 라이브러리나 도구의 사용법은 각 공식 문서를 확인하세요.
클라이언트를 구현하거나 설정할 때
- 참조 식별자를 URL이나 설정 같은 클라이언트 쪽 입력에서 만들고, 인증서 내용에서 만들지 않는다(§6.1.1).
- DNS 해석 중 거친 중간 이름을 참조 식별자로 쓰지 않는다(§6.1.1).
- 이름 검사에서 CN으로 대체(fallback)하지 않는다(§2).
- DNS 이름은 레이블 단위 대소문자 무시 ASCII 비교, IDN은 A-label로 바꾼 뒤 비교한다(§6.3).
- 와일드카드는 하나뿐이고 가장 왼쪽 레이블 전체일 때만 인정하며, 레이블 하나에만 대응시킨다(§6.3).
- IP로 접속하면 SAN
iPAddress와 옥텟 단위로 정확히 비교한다(§6.2, §6.4). - IP 주소와 도메인 이름의 분류를 시스템 전체에서 일관되게 한다(§3, §7.4).
- 자동화 클라이언트는 불일치 시 기본적으로 연결을 끊고 기록한다. 검사를 끄는 옵션이 있다면 기본값은 켜짐이다(§6.6).
- 이름 검사와 별도로 인증 경로, 만료, 폐기 검사가 수행되는지 확인한다(§1.2, §6).
인증서를 요청하거나 서버를 설정할 때
- 클라이언트가 접속할 호스트 이름이 SAN의
dNSName으로 들어 있는지 확인한다. CN에만 있으면 안 된다(§2, 부록 A). -
*.bigcompany.example하나로bigcompany.example과 여러 단계 하위 이름까지 덮인다고 가정하지 않는다(§6.3, 위 표의 도출 예시). - 국제화 도메인은 A-label 형태로 넣는다(§2).
- IP 주소로 접속을 받는다면 그 주소를
iPAddress항목으로 넣고, SNI 없는 연결에 그 인증서가 제시되는지 확인한다(§4.2, §7.4). - 한 서비스를 식별하는 데 필요한 만큼만 이름을 넣는다. 인증서의 이름 집합 중 가장 약한 서버가 전체의 강도를 결정한다(§5, §7.5).
이름 일치가 보장하지 않는 것
이름 비교에 성공했다고 연결이 안전하다는 결론이 나오지는 않습니다. RFC 9525가 스스로 정한 범위는 다음과 같습니다.
- RFC 9525는 PKIX(RFC 5280)의 발급·검증 규칙을 대체하지 않습니다. 인증서 구문, 이름 제약이나 확장 키 용도 같은 확장, 인증 경로 처리는 PKIX가 다룹니다(§1.2).
- 다루는 것은 말단(end entity) 서버 인증서의 이름뿐이며, 체인을 만들거나 그 유효성을 검사하지 않습니다. 제대로 인증하려면 애플리케이션이 인증 경로 전체를 검증해야 합니다(§1.2).
- 만료나 폐기 같은 추가 검사도 필요하지만, 서비스 신원 검증이 아니므로 방법은 범위 밖입니다(§6).
- 클라이언트가 신뢰하는 CA가 발급한 인증서는 모두 신뢰한다고 가정하며, 악성 서버나 버그 있는 애플리케이션에 대한 추가 검사는 애플리케이션이나 클라이언트의 몫입니다(§7.7).
- 입력 자체가 잘못되었다면(예: 피싱 링크를 클릭한 경우) 이름 검증이 성공해도 의도하지 않은 서비스와 통신하게 될 수 있습니다(§6.1.1).
- RFC는 와일드카드 관련 공격 사례가 처음의 평문 HTTP 연결을 가로채는 데 의존한다고 언급합니다(§7.1). 첫 연결을 HTTPS로 강제하는 문제는 이름 비교와 별개이며, HSTS 글에서 다룹니다.
참고 자료
아래 공식 자료는 2026-10-18에 확인했습니다.
- RFC 9525, “Service Identity in TLS” (텍스트): https://www.rfc-editor.org/rfc/rfc9525.txt
- RFC 9525 정보 페이지 (RFC Editor): https://www.rfc-editor.org/info/rfc9525