인터넷 엔지니어링 태스크 포스 (IETF) R. Shekh-Yusef, 편집자
요청 의견(Request for Comments): 7616 Avaya
Obsoletes: 2617 D. Ahrens
분류: 표준 트랙 독립
ISSN: 2070-1721 S. Bremer
Netzkonform
2015년 9월

HTTP 다이제스트 액세스 인증


초록

하이퍼텍스트 전송 프로토콜(HTTP)은 서버가 클라이언트 요청에 대해 챌린지-응답 방식의 인증을 요구할 수 있고, 클라이언트가 인증 정보를 제공할 수 있도록 하는 간단한 챌린지-응답 인증 메커니즘을 제공합니다. 이 문서는 HTTP 인증 메커니즘과 함께 사용할 수 있는 HTTP 다이제스트 인증 스킴을 정의합니다.

이 메모의 상태

이 문서는 인터넷 표준 트랙 문서입니다.

이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산물입니다. 이는 IETF 커뮤니티의 합의를 반영합니다. 이 문서는 공개 검토를 거쳤고 인터넷 엔지니어링 운영 그룹(IESG)에 의해 게재 승인을 받았습니다. 인터넷 표준에 대한 추가 정보는 RFC 5741의 섹션 2에서 확인할 수 있습니다.

이 문서의 현재 상태, 정정 사항(errata), 및 피드백 제공 방법에 대한 정보는 http://www.rfc-editor.org/info/rfc7616에서 확인할 수 있습니다.

Copyright Notice

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.

1. 소개

HTTP는 서버가 클라이언트 요청에 대해 챌린지-응답 방식의 인증을 요구할 수 있고, 클라이언트가 인증 정보를 제공할 수 있도록 하는 간단한 챌린지-응답 인증 메커니즘을 제공합니다. 이 문서는 HTTP 인증 메커니즘과 함께 사용할 수 있는 HTTP 다이제스트 인증 스킴을 정의합니다.

이 문서는 [RFC2617]를 확장하지만 일반적으로 하위 호환성을 유지합니다. 이 명세가 도입한 새로운 기능은 부록 A를 참조하십시오.

챌린지-응답 인증 메커니즘의 세부사항은 "Hypertext Transfer Protocol (HTTP/1.1): Authentication" [RFC7235]에 지정되어 있습니다.

이 문서와 "Basic" 인증 스킴의 정의([RFC7617]), "HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields"([RFC7615]), 및 "Hypertext Transfer Protocol (HTTP/1.1): Authentication"([RFC7235])을 결합하면 [RFC2617]를 폐기합니다.

1.1. 용어

이 문서에서 키워드 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" 및 "OPTIONAL"은 [RFC2119]에 설명된 대로 해석되어야 합니다.

2. 구문 규약

2.1. 예시

명확성과 가독성을 위해, 이 문서의 예시에서 확장된 매개변수나 헤더 필드 및 매개변수는 여러 줄로 나뉘어 표시될 수 있습니다. 이 문서에서 들여쓰기된 모든 줄은 앞선 줄의 연속입니다.

2.2. ABNF

이 명세는 [RFC5234]의 확장된 Backus-Naur 형식(ABNF) 표기법과 [RFC7230]의 ABNF List 확장을 사용합니다.

3. 다이제스트 액세스 인증 방식

3.1. 전체 동작

다이제스트 스킴은 간단한 챌린지-응답 패러다임에 기반합니다. 다이제스트 스킴은 논스(nonce) 값을 사용하여 챌린지하고, 사용자 이름 해싱이 지원되는지 나타낼 수 있습니다. 유효한 응답은 사용자 이름, 비밀번호, 주어진 논스 값, HTTP 메소드 및 요청된 URI의 비키드(unkeyed) 다이제스트를 포함합니다. 이렇게 하면 비밀번호가 평문으로 전송되지 않으며, 서버에서 받은 표시(서버의 지시에 따라)대로 사용자 이름을 해시할 수 있습니다. 사용자 이름과 비밀번호는 본 문서에서 다루지 않는 방식으로 사전에 합의되어 있어야 합니다.

3.2. 다이제스트 값의 표현

서버가 비키드 다이제스트 또는 다이제스트를 생성하는 데 사용한 알고리즘을 지정할 수 있도록 선택적 헤더 필드가 허용됩니다. 이 문서는 SHA-256 및 SHA-512/256 알고리즘을 추가합니다. [RFC2617]와의 하위 호환성을 유지하기 위해 MD5 알고리즘은 여전히 지원되지만 권장되지 않습니다.

다이제스트의 크기는 사용된 알고리즘에 따라 다릅니다. 다이제스트의 비트는 가장 상위 비트에서 최하위 비트로, 4비트씩 잘라 다음과 같이 ASCII 표현으로 변환됩니다. 4비트의 각 시퀀스는 익숙한 16진 표기(문자 0123456789abcdef)로 표현됩니다. 즉, 이진 0000은 문자 '0'으로, 0001은 '1'로, 1111은 'f'로 표현됩니다. MD5 알고리즘이 사용된 경우 MD5 다이제스트는 32개의 16진 문자로 표현되며, SHA-256 및 SHA-512/256은 64개의 16진 문자로 표현됩니다.

3.3. WWW-Authenticate 응답 헤더 필드

서버가 접근 보호된 객체에 대한 요청을 수신했으나 허용 가능한 Authorization 헤더 필드가 전송되지 않은 경우, 서버는 "401 Unauthorized" 상태 코드와 함께 위에 정의된 프레임워크에 따른 Digest 스킴을 사용하는 WWW-Authenticate 헤더 필드로 응답합니다. 헤더 필드의 값은 다음 목록의 매개변수를 포함할 수 있습니다:

realm

  • 사용자에게 표시되어 어느 사용자 이름과 비밀번호를 사용할지 알 수 있게 하는 문자열입니다. 이 문자열은 인증을 수행하는 호스트의 이름을 최소한 포함해야 하며, 추가로 접근 가능한 사용자 집합을 나타낼 수도 있습니다. 예시로는 "registered_users@example.com"이 있습니다. (자세한 내용은 RFC7235 섹션 2.2 참조.)

domain

  • 보호 공간을 정의하는, 인용된 공백으로 구분된 URI 목록입니다(URI 문법은 [RFC3986] 참조). 만약 URI가 경로-절대(path-absolute)라면 정규화된 루트 URL에 상대적입니다. 이 목록의 절대-URI는 웹-오리진과 다른 서버를 가리킬 수 있습니다. 클라이언트는 이 목록을 사용하여 동일한 인증 정보를 보낼 수 있는 URI 집합을 결정할 수 있습니다: 이 목록의 어떤 URI가 접두사인(둘 다 절대화된 후) 모든 URI는 동일한 보호 공간에 속한다고 간주할 수 있습니다. 이 매개변수가 생략되거나 값이 비어 있으면, 클라이언트는 보호 공간이 웹-오리진의 모든 URI로 구성된다고 가정해야 합니다.
  • 이 매개변수는 항상 프록시 전체가 보호 공간인 Proxy-Authenticate 헤더 필드에는 의미가 없습니다; 만약 존재하면 무시되어야 합니다.

nonce

  • 서버가 지정하는 문자열로, 401 응답이 만들어질 때마다 고유하게 생성되는 것이 바람직합니다. 이 문자열은 Base64 또는 16진 데이터일 것을 권장합니다. 구체적으로 이 문자열은 인용 문자열로 헤더 필드 라인에 전달되므로, 큰따옴표 문자(")는 적절히 이스케이프되지 않는 한 허용되지 않습니다.
  • 논스의 내용은 구현에 따라 다릅니다. 구현의 품질은 적절한 선택에 달려 있습니다. 예를 들어 논스는 다음을 Base64로 인코딩한 형태로 구성될 수 있습니다:
             timestamp H(timestamp ":" ETag ":" secret-data)
    
  • 여기서 timestamp는 서버가 생성한 시간으로 마이크로초나 나노초 또는 기타 반복되지 않는 값을 포함하는 것이 바람직합니다; ETag는 요청된 엔터티와 연관된 HTTP ETag 헤더 필드의 값이며; secret-data는 서버만 알고 있는 데이터입니다. 이러한 형태의 논스를 사용하면, 서버는 클라이언트로부터 받은 인증 헤더 필드를 수신한 후 해시 부분을 재계산하고 헤더 필드의 논스와 일치하지 않거나 timestamp 값이 충분히 최신이 아니면 요청을 거부할 수 있습니다. 이렇게 하여 서버는 논스의 유효 기간을 제한할 수 있습니다. ETag 포함은 리소스가 갱신된 경우에 대한 재생 요청을 방지합니다. 논스에 클라이언트의 IP 주소를 포함시키면 논스 재사용을 원래 클라이언트를 동일하게 제한할 수 있을 것 같지만, 단일 사용자의 요청이 다른 프록시를 통해 가는 경우가 많아 이는 실패합니다. 또한 IP 주소 스푸핑이 어렵지 않습니다.
  • 구현체는 재생 공격을 방지하기 위해 이전에 사용된 논스나 이전에 사용된 다이제스트를 수락하지 않기로 선택할 수 있습니다. 또는 구현체는 POST나 PUT 요청에 대해 일회용 논스나 다이제스트를 사용하고 GET 요청에는 타임스탬프를 사용할 수 있습니다. 관련 문제에 대한 상세 내용은 이 문서의 섹션 5를 참조하십시오.
  • 논스는 클라이언트에게 불투명합니다.

opaque

  • 서버가 지정하는 데이터 문자열로, 동일한 보호 공간의 URI에 대한 후속 요청의 Authorization 헤더 필드에서 클라이언트가 변경하지 않고 반환해야 하는 값입니다. 이 문자열은 Base64나 16진 데이터일 것을 권장합니다.

stale

  • 이전 클라이언트 요청이 논스 값이 오래되어(replay 또는 만료) 거부되었음을 나타내는 대소문자 구분 없는 플래그입니다. 만약 stale이 true라면, 클라이언트는 사용자에게 새 사용자 이름과 비밀번호를 요구하지 않고 새 암호화된 응답으로 단순히 재시도할 수 있습니다. 서버는 논스가 유효하지 않은 요청을 수신한 경우에만 stale을 true로 설정해야 합니다. stale이 false이거나 true가 아닌 다른 값이거나 stale 매개변수가 없으면 사용자 이름 및/또는 비밀번호가 유효하지 않으며 새 값을 받아야 합니다.

algorithm

  • 다이제스트와 비키드 다이제스트를 생성하는 데 사용된 알고리즘을 나타내는 문자열입니다. 이 매개변수가 없으면 기본값은 "MD5"로 간주됩니다. 알고리즘을 이해하지 못하면 챌린지를 무시해야 합니다(그리고 여러 챌린지가 있다면 다른 챌린지를 사용해야 합니다).
  • 다이제스트 메커니즘과 함께 사용될 때, 각 알고리즘은 세션 변형과 비세션 변형의 두 가지 변형을 가집니다. 비세션 변형은 "<algorithm>"으로 표기되며 예: "SHA-256", 세션 변형은 "<algorithm>-sess"로 표기되며 예: "SHA-256-sess"입니다.
  • 이 문서에서는 데이터 "data"에 대해 다이제스트 알고리즘을 적용한 결과 문자열을 H(data)로 표기하고, 비키드 다이제스트 알고리즘을 적용한 결과를 KD(secret, data)로 표기합니다. KD는 Keyed Digest를 의미하며, 표기법 unq(X)는 인용 문자열 X에서 둘러싼 인용부호를 제거하고 이스케이프 슬래시를 제거한 값을 의미합니다.
         For "<algorithm>" and "<algorithm>-sess"
    
             H(data) = <algorithm>(data)
    
         and
    
             KD(secret, data) = H(concat(secret, ":", data))
    
  • 예를 들어:
         For the "SHA-256" and "SHA-256-sess" algorithms
    
             H(data) = SHA-256(data)
    
  • 즉, 다이제스트는 secret과 ":" 그리고 data를 연결한 것에 대해 "<algorithm>"을 적용한 것입니다. "<algorithm>-sess"는 효율적인 제3자 인증 서버 사용을 허용하기 위한 것이며, 사용상의 차이는 섹션 3.4.2의 설명을 참조하십시오.

qop

  • 이 매개변수는 모든 구현체에서 사용되어야 합니다. 이는 서버가 지원하는 "protection의 품질(quality of protection)" 값들을 나타내는 하나 이상의 토큰으로 된 인용 문자열입니다. 값 "auth"는 인증을, 값 "auth-int"는 무결성 보호를 동반한 인증을 나타냅니다. 이 선택의 적용을 위한 response 매개변수 계산에 대한 설명은 아래를 참조하십시오. 인식하지 못하는 옵션은 무시되어야 합니다.

charset

  • 서버가 지원하는 인코딩 스킴을 나타내기 위해 사용하는 선택적 매개변수입니다. 허용되는 유일한 값은 "UTF-8"입니다.

userhash

  • 서버가 사용자 이름 해싱을 지원함을 나타내기 위해 사용하는 선택적 매개변수입니다. 유효한 값은 "true" 또는 "false"이며 기본값은 "false"입니다.

역사적 이유로, 송신자는 다음 매개변수들에 대해서만 인용 문자열(quoted string) 문법을 생성해야 합니다: realm, domain, nonce, opaque, 및 qop.

역사적 이유로, 송신자는 다음 매개변수들에 대해 인용 문자열 문법을 생성해서는 안 됩니다: stale 및 algorithm.

3.4. Authorization 헤더 필드

클라이언트는 요청을 재시도할 때 Digest 스킴을 사용하는 Authorization 헤더 필드를 포함하여 전송해야 합니다. opaque 및 algorithm 필드의 값은 요청 대상 엔터티에 대한 WWW-Authenticate 응답 헤더 필드에서 제공된 값이어야 합니다.

요청은 다음 목록의 매개변수를 포함할 수 있습니다:

response

  • 아래에 정의된 대로 계산된 16진 숫자 문자열입니다; 이는 사용자가 비밀번호를 알고 있음을 증명합니다.

username

  • 지정된 realm에서의 사용자 이름입니다. 인용 문자열은 평문 사용자 이름 또는 16진 표기된 해시 코드를 포함합니다. 만약 사용자 이름에 ABNF quoted-string 생산식 안에서 허용되지 않는 문자가 포함되어 있다면 username* 매개변수를 사용할 수 있습니다. 동일한 헤더 옵션에서 username과 username*을 동시에 보내는 것은 오류로 처리되어야 합니다.

username*

  • userhash 매개변수 값이 "false"로 설정되어 있고 사용자 이름에 ABNF quoted-string에서 허용되지 않는 문자가 포함된 경우, 사용자는 이 매개변수를 사용하여 [RFC5987]에 정의된 확장 표기법으로 사용자 이름을 보낼 수 있습니다.

realm

  • "realm" 정의는 섹션 3.3를 참조하십시오.

uri

  • HTTP 요청의 유효한 요청 URI(Effective Request URI, RFC7230 섹션 5.5)입니다; 이는 프록시가 전송 중에 요청 대상("request-target", RFC7230 섹션 3.1.1)을 변경할 수 있기 때문에 중복 표시됩니다.

qop

  • 클라이언트가 메시지에 적용한 "protection의 품질"을 나타냅니다. 그 값은 WWW-Authenticate 헤더 필드에서 서버가 지원한다고 표시한 대안 중 하나여야 합니다. 이 값들은 response 계산에 영향을 줍니다. 이는 단일 토큰이며 WWW-Authenticate에서의 인용된 대안 목록이 아님에 유의하십시오.

cnonce

  • 이 매개변수는 모든 구현체에서 사용되어야 합니다. cnonce 값은 클라이언트가 제공하는 불투명한 인용된 ASCII 전용 문자열로, 선택 평문 공격을 피하고 상호 인증을 제공하며 일부 메시지 무결성 보호를 제공하기 위해 클라이언트와 서버 둘 다에서 사용됩니다. rspauth 및 response 값의 계산에 대한 설명을 참조하십시오.

nc

  • 이 매개변수는 모든 구현체에서 사용되어야 합니다. nc는 "nonce count"를 의미합니다. nc 값은 이 요청에 사용된 논스 값으로 클라이언트가 전송한 요청의 수(현재 요청 포함)를 16진수로 카운트한 값입니다. 예를 들어 주어진 논스 값에 대한 첫 번째 요청에서는 클라이언트가 "nc=00000001"을 전송합니다. 이 매개변수의 목적은 서버가 자체 카운트를 유지함으로써 요청 재생을 탐지하기 위함입니다 -- 동일한 nc 값이 두 번 보이면 요청은 재생입니다. response 값 구성에 대한 설명을 참조하십시오.

userhash

  • 선택적 매개변수는 클라이언트가 사용자 이름을 해시했음을 나타내기 위해 사용됩니다. 유효한 값은 "true" 또는 "false"이며 기본값은 "false"입니다.

역사적 이유로, 송신자는 다음 매개변수들에 대해서만 인용 문자열 문법을 생성해야 합니다: username, realm, nonce, uri, response, cnonce, 및 opaque.

역사적 이유로, 송신자는 다음 매개변수들에 대해 인용 문자열 문법을 생성해서는 안 됩니다: algorithm, qop, 및 nc.

매개변수나 그 값이 부적절하거나 필수 매개변수가 누락된 경우, 적절한 응답은 4xx 오류 코드입니다. 응답이 유효하지 않으면 로그인 실패를 기록해야 합니다(권장), 단일 클라이언트로부터 반복적인 로그인 실패는 공격자가 비밀번호를 추측하려는 시도로 보일 수 있습니다. 서버 구현체는 로그에 평문 비밀번호(예: username 필드에 입력된)를 남기지 않도록 기록하는 정보에 주의해야 합니다.

위의 response 정의는 그 값의 인코딩을 나타냅니다. 다음 정의는 값이 어떻게 계산되는지를 보여줍니다.

3.4.1. 응답

qop 값이 "auth" 또는 "auth-int"인 경우:

      response = <"> < KD ( H(A1), unq(nonce)
                                   ":" nc
                                   ":" unq(cnonce)
                                   ":" unq(qop)
                                   ":" H(A2)
                          ) <">

A1 및 A2의 정의는 아래를 참조하십시오.

3.4.2. A1

algorithm 매개변수의 값이 "<algorithm>"인 경우, 예: "SHA-256", A1은 다음과 같습니다:

      A1       = unq(username) ":" unq(realm) ":" passwd

여기서

      passwd   = < user's password >

algorithm 매개변수의 값이 "<algorithm>-sess"인 경우, 예: "SHA-256-sess", A1은 서버의 챌린지에서 제공된 논스 값과 클라이언트가 챌린지를 수신한 후 응답 요청에서 제공한 cnonce 값을 사용하여 계산됩니다. 이때 서버 챌린지의 논스를 nonce-prime이라 하고 응답의 클라이언트 논스를 cnonce-prime이라 부르며 A1을 다음과 같이 구성합니다:

      A1       = H( unq(username) ":" unq(realm) ":" passwd )
                     ":" unq(nonce-prime) ":" unq(cnonce-prime)

이는 각 "인증 세션"마다 다른 인증을 위한 "세션 키"를 생성하여 어느 한 키로 해시되는 자료의 양을 제한합니다. (참고: 인증 세션에 대한 추가 논의는 섹션 3.6 참조.) 서버는 A1 값을 생성하기 위해 사용자 자격증명의 해시만 필요로 하므로, 이 구성은 제3자 인증 서비스와 함께 사용되어 웹 서버가 실제 비밀번호 값을 알 필요가 없게 할 수 있습니다. 이러한 프로토콜의 명세는 본 명세의 범위를 벗어납니다.

3.4.3. A2

qop 매개변수의 값이 "auth"이거나 지정되지 않은 경우, A2는 다음과 같습니다:

      A2       = Method ":" request-uri

qop 값이 "auth-int"인 경우, A2는 다음과 같습니다:

      A2       = Method ":" request-uri ":" H(entity-body)

3.4.4. 사용자 이름 해싱

클라이언트에서 서버로의 사용자 이름 전송을 보호하기 위해, 서버는 WWW-Authenticate 헤더 필드에 userhash 매개변수를 "true"로 설정하는 것이 권장됩니다.

클라이언트가 userhash 매개변수를 지원하고 WWW-Authenticate 헤더 필드의 userhash 값이 "true"로 설정된 경우, 클라이언트는 사용자 자격증명을 해시하는 데 사용된 것과 동일한 알고리즘을 사용하여 사용자 이름의 해시를 계산하고 Authorization 헤더 필드에 userhash 매개변수와 값 "true"를 포함해야 합니다(MUST). 클라이언트가 사용자 이름을 해시 값으로 제공하지 않거나 userhash 매개변수에 "true"를 제공하지 않으면 서버는 요청을 거부할 수 있습니다(MAY).

다음은 클라이언트가 자격증명 해시에 사용된 것과 동일한 알고리즘을 사용하여 사용자 이름을 해시하기 위해 수행할 연산입니다:

   username = H( unq(username) ":" unq(realm) )

3.4.5. 매개변수 값 및 인용 문자열

username 값과 같은 많은 매개변수의 값이 "quoted-string"으로 정의되어 있다는 점에 유의하십시오. 그러나 "unq" 표기법은 A1 문자열을 형성할 때 둘러싼 인용부호가 제거된다는 것을 나타냅니다. 따라서 Authorization 헤더 필드에 다음과 같은 필드들이 포함되어 있다면

   username="Mufasa", realm="myhost@example.com"

그리고 사용자 Mufasa의 비밀번호가 "Circle Of Life"라면, H(A1)는 소화된 문자열에서 인용부호 없이 H(Mufasa:myhost@example.com:Circle Of Life)가 됩니다.

다이제스트 함수 H()가 적용되는 문자열에는, 그 공백이 다이제스트될 문자열을 구성하는 인용 문자열이나 엔터티 본문에 존재하지 않는 한 공백이 허용되지 않습니다. 예를 들어 위에 예시된 A1 문자열은 다음과 같아야 합니다

   Mufasa:myhost@example.com:Circle Of Life

콜론 양쪽에는 공백이 없어야 하지만, 비밀번호 값에 사용된 단어들 사이의 공백은 포함됩니다. 마찬가지로 H()로 다이제스트되는 다른 문자열들도 필드를 구분하는 콜론 양쪽에 공백이 있어서는 안 되며, 그 공백이 인용 문자열이나 다이제스트되는 엔터티 본문 안에 있었던 경우를 제외합니다.

또한 무결성 보호가 적용된 경우(qop=auth-int), H(entity-body)는 메시지 본문이 아니라 엔터티 본문의 해시임에 유의하십시오 — 이는 송신자가 어떤 전송 인코딩도 적용하기 전에 계산되며 수신자가 전송 인코딩을 제거한 이후에 계산됩니다. 이에는 multipart 경계와 모든 multipart 콘텐츠 타입의 각 부분에 포함된 임베디드 헤더 필드도 포함됩니다.

3.4.6. 여러 고려사항

"Method" 값은 RFC 7230의 Section 3.1.1에 규정된 바와 같이 US-ASCII 문자로 된 HTTP 요청 메소드입니다. "request-target" 값은 RFC 7230의 Section 3.1.1에 규정된 요청 라인에서의 request-target입니다. 이 값은 MAY "*"이거나, RFC 7230의 Section 2.7에 규정된 "absolute-URI" 또는 "absolute-path"일 수 있으나, request-target과 일치해야 합니다(MUST). 특히 request-target이 "absolute-URI"인 경우에는 이 값도 "absolute-URI"이어야 합니다(MUST). cnonce 값은 선택 평문 공격을 방지하기 위해 클라이언트가 선택하는 값입니다.

인증 서버는 "uri" 매개변수로 지정된 리소스가 Request-Line에 지정된 리소스와 동일함을 보장해야 합니다(MUST); 동일하지 않다면 서버는 400 Bad Request 오류를 반환하는 것이 권장됩니다(SHOULD). (이는 공격의 징후일 수 있으므로 서버 구현자는 그러한 오류를 로깅하는 것을 고려할 수 있습니다.) 요청 URL에서 이 필드로 정보를 중복해서 포함하는 목적은 중간 프록시가 클라이언트의 Request-Line을 변경할 가능성에 대처하기 위함입니다. 변경된(그러나 의미상 동등한 것으로 보이는) 요청은 클라이언트가 계산한 것과 동일한 다이제스트를 생성하지 않을 것입니다.

구현자는 인증된 트랜잭션이 공유 캐시와 어떻게 상호작용해야 하는지에 유의해야 합니다(참조: RFC7234).

3.5. Authentication-Info 및 Proxy-Authentication-Info 헤더 필드

Authentication-Info 헤더 필드와 Proxy-Authentication-Info 헤더 필드(RFC7615)는 서버가 클라이언트 응답의 성공적인 인증과 관련된 정보를 전달하는 데 사용할 수 있는 일반적인 필드입니다(MAY).

Digest 인증 스킴은 확인 응답에서 Authentication-Info 헤더 필드를 추가하고 다음 목록의 매개변수를 포함할 수 있습니다(MAY):

nextnonce

  • nextnonce 매개변수의 값은 서버가 클라이언트가 이후의 인증 응답에 사용하기를 원하는 논스입니다. 서버는 일회용 논스 구현이나 기타 방식으로 논스를 변경하기 위해 Authentication-Info 헤더 필드를 nextnonce 필드와 함께 보낼 수 있습니다(MAY). 만약 nextnonce 필드가 존재하면, 클라이언트는 차기 요청의 Authorization 헤더를 구성할 때 이를 사용하는 것이 SHOULD입니다. 클라이언트가 이를 사용하지 않으면 서버가 "stale=true"로 재인증을 요구할 수 있습니다(MAY).
    • 서버 구현자는 이 메커니즘 사용의 성능 영향에 대해 신중히 고려해야 합니다; 모든 응답이 다음 요청에서 반드시 사용되어야 하는 nextnonce를 포함하면 파이프라인된 요청은 불가능해집니다. 요청 파이프라이닝을 허용하기 위해 오래된 논스 값을 일정 기간 허용하는 것의 보안과 성능 상의 절충을 고려해야 합니다. nc 매개변수의 사용은 새 서버 논스가 주는 대부분의 보안 이점을 유지하면서 파이프라이닝에 미치는 악영향을 줄일 수 있습니다.

qop

  • 서버가 응답에 적용한 "protection의 품질" 옵션을 나타냅니다. 값 "auth"는 인증을, 값 "auth-int"는 무결성 보호를 동반한 인증을 나타냅니다. 서버는 응답에서 qop 매개변수에 대해 요청에서 클라이언트가 보낸 값과 동일한 값을 사용하는 것이 SHOULD입니다.

rspauth

  • rspauth 매개변수의 선택적 응답 다이제스트는 상호 인증을 지원합니다 — 서버는 사용자의 비밀을 알고 있음을 증명하며, qop=auth-int인 경우 응답에 대한 제한된 무결성 보호도 제공합니다. rspauth 값은 Authorization 헤더 필드의 response 계산과 동일하게 계산되지만, 요청의 Authorization 헤더 필드에서 qop가 "auth"로 설정되었거나 지정되지 않은 경우 A2는
  •       A2       = ":" request-uri
    
    이고, "qop=auth-int"인 경우에는 A2가
          A2       = ":" request-uri ":" H(entity-body)
    
    입니다.

cnonce and nc

  • cnonce 값과 nc 값은 이 메시지가 응답하는 클라이언트 요청에 대한 것과 동일해야 합니다(MUST). rspauth, cnonce, 및 nc 매개변수는 "qop=auth" 또는 "qop=auth-int"가 지정된 경우 반드시 포함되어야 합니다(MUST).

Authentication-Info 헤더 필드는 청크 전송 인코딩을 통해 전송된 HTTP 메시지의 트레일러에 허용됩니다.

역사적 이유로, 송신자는 다음 매개변수들에 대해서만 인용 문자열 문법을 생성해야 합니다: nextnonce, rspauth, 및 cnonce(MUST).

역사적 이유로, 송신자는 다음 매개변수들에 대해 인용 문자열 문법을 생성해서는 안 됩니다: qop 및 nc(MUST NOT).

역사적 이유로, nc 값은 정확히 8개의 16진 숫자여야 합니다(MUST).

3.6. 다이제스트 동작

서버는 Authorization 헤더 필드를 수신하면 제출된 username에 해당하는 비밀번호를 조회하여 그 유효성을 확인할 수 있습니다(MAY). 그런 다음 서버는 클라이언트가 수행한 것과 동일한 다이제스트 연산(예: MD5, SHA-256)을 수행하고 그 결과를 주어진 response 값과 비교해야 합니다(MUST).

HTTP 서버는 실제로 사용자의 평문 비밀번호를 알 필요가 없다는 점에 유의하십시오. 서버가 H(A1)를 알고 있는 한 Authorization 헤더 필드의 유효성을 검증할 수 있습니다.

클라이언트의 WWW-Authenticate 챌린지에 대한 응답은 해당 보호 공간과의 인증 세션을 시작합니다. 인증 세션은 클라이언트가 보호 공간 내의 어떤 서버로부터든 다른 WWW-Authenticate 챌린지를 받을 때까지 지속됩니다. 클라이언트는 인증 세션과 관련된 username, password, nonce, nonce count, opaque 값을 기억하여 해당 보호 공간 내의 향후 요청에서 Authorization 헤더 필드를 구성하는 데 사용하는 것이 SHOULD입니다. Authorization 헤더 필드는 사전 전송(preemptive)으로 포함될 수 있으며, 이는 서버 효율성을 향상시키고 추가 챌린지 왕복을 피합니다(MAY). 서버는 nonce 값이 신선하지 않을 수 있음에도 불구하고 오래된 Authorization 헤더 정보를 수락할 수 있습니다(MAY). 또는 서버는 WWW-Authenticate 헤더 필드에 새 nonce 값을 담아 401 응답을 반환하여 클라이언트가 요청을 재시도하게 할 수 있으며, 이 응답에 "stale=true"를 지정하면 서버는 클라이언트에게 새 nonce로 재시도하되 새 사용자 이름과 비밀번호를 다시 묻지 않도록 지시합니다(MAY).

클라이언트가 세션 동안 서버가 제공한 opaque 매개변수의 값을 반환해야 하기 때문에, opaque 데이터는 인증 세션 상태 정보를 전달하는 데 사용할 수 있습니다. (그러나 이러한 용도는 논스에 상태를 포함시키는 것이 더 쉽고 안전하게 달성될 수 있습니다.) 예를 들어, 서버는 첫 401 응답에 domain 매개변수를 포함하여 두 번째 서버의 URI를 값으로 포함시키고, opaque 매개변수에 상태 정보를 넣을 수 있습니다. 클라이언트는 요청을 재시도할 것이고, 그 시점에 서버는 두 번째 서버의 URI를 가리키는 HTTP 리디렉션을 응답으로 보낼 수 있습니다. 클라이언트는 리디렉션을 따라가며 그 요청에 opaque 데이터를 포함한 Authorization 헤더 필드를 전달할 것입니다.

프록시는 Digest 액세스 인증 방식에서 완전히 투명해야 합니다(MUST). 즉, 프록시는 WWW-Authenticate, Authentication-Info 및 Authorization 헤더 필드를 변경하지 않고 전달해야 합니다(MUST). 프록시가 서버로 요청을 전달하기 전에 클라이언트를 인증하려는 경우에는 아래 섹션 3.8에 설명된 Proxy-Authenticate 및 Proxy-Authorization 헤더 필드를 사용하여 수행할 수 있습니다.

3.7. 보안 프로토콜 협상

서버가 클라이언트가 처리할 수 있는 보안 스킴을 알 수 있는 것은 유용합니다.

서버가 Digest를 인증 방법으로 요구하고 싶지만 클라이언트가 이를 지원하는지 모를 수도 있습니다. 클라이언트는 서버가 자신이 처리할 수 없는 인증 스킴만 지정한 경우에도 우아하게 실패하는 것이 권장됩니다.

서버가 리소스에 대한 접근 요청을 수신하면, 서버는 "401 Unauthorized" 응답으로 하나 이상의 WWW-Authenticate 헤더 필드를 포함하여 클라이언지를 챌린지할 수 있습니다. 서버가 여러 챌린지를 응답에 포함하면 각 챌린지는 서로 다른 다이제스트 알고리즘을 사용해야 합니다(MUST). 서버는 우선순위가 높은 알고리즘부터 시작하여 덜 선호되는 알고리즘 순서로 이러한 챌린지를 응답에 추가해야 합니다(MUST).

이 명세는 다음 알고리즘들을 정의합니다:

  • SHA2-256 (구현 필수)
  • SHA2-512/256 (백업 알고리즘)
  • MD5 (하위 호환성용)

클라이언트가 첫 번째 챌린지를 수신하면, 로컬 정책이 달리 지시하지 않는 한 클라이언트는 자신이 지원하는 첫 번째 챌린지를 사용하는 것이 SHOULD입니다.

3.8. Proxy-Authenticate 및 Proxy-Authorization

Digest 인증 스킴은 Proxy-Authenticate 및 Proxy-Authorization 헤더 필드를 사용하여 프록시-사용자, 프록시-프록시 또는 프록시-오리진 서버 간의 인증에도 사용할 수 있습니다. 이 헤더 필드들은 HTTP/1.1 규격의 Section 4.3Section 4.4에 규정된 Proxy-Authenticate 및 Proxy-Authorization 헤더 필드의 사례이며, 그 동작은 해당 문서에서 설명된 제한을 따릅니다. 프록시 인증을 위한 트랜잭션은 위에서 이미 설명한 것과 매우 유사합니다. 인증이 필요한 요청을 수신하면 프록시/서버는 "407 Proxy Authentication Required" 응답과 함께 "Proxy-Authenticate" 헤더 필드를 발행해야 합니다. Proxy-Authenticate 헤더 필드에 사용된 다이제스트 챌린지는 위의 섹션 3.3에서 정의한 WWW-Authenticate의 다이제스트 챌린지와 동일합니다.

클라이언트/프록시는 그런 다음 요청을 Proxy-Authorization 헤더 필드와 함께 재전송해야 하며, 해당 매개변수는 위의 섹션 3.4에 지정된 Authorization 헤더 필드의 매개변수와 동일해야 합니다(MUST).

후속 응답에서 서버는 Authentication-Info 헤더 필드와 동일한 매개변수를 갖는 Proxy-Authentication-Info를 전송합니다.

원칙적으로 클라이언트가 프록시와 최종 서버 둘 다에 대해 인증하라는 요청을 받을 수 있지만, 동일한 응답에서 두 인증을 요구받는 일은 없습니다.

3.9. 예시

3.9.1. SHA-256 및 MD5 예시

다음 예시는 GET 요청을 통해 보호된 문서를 서버에 요청한다고 가정합니다. 문서의 URI는 "http://www.example.org/dir/index.html"입니다. 클라이언트와 서버는 이 문서에 대한 username이 "Mufasa"이고 비밀번호가 "Circle of Life"(세 단어 사이에 한 칸씩 공백)임을 알고 있습니다.

클라이언트가 문서를 처음 요청할 때 Authorization 헤더 필드가 전송되지 않으므로 서버는 다음과 같이 응답합니다:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
    realm="http-auth@example.org",
    qop="auth, auth-int",
    algorithm=SHA-256,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
WWW-Authenticate: Digest
    realm="http-auth@example.org",
    qop="auth, auth-int",
    algorithm=MD5,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

클라이언트는 사용자에게 username과 password를 묻고, 클라이언트가 MD5 다이제스트를 선택하면 다음과 같은 Authorization 헤더 필드를 포함한 새 요청으로 응답합니다:

Authorization: Digest username="Mufasa",
    realm="http-auth@example.org",
    uri="/dir/index.html",
    algorithm=MD5,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    nc=00000001,
    cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
    qop=auth,
    response="8ca523f5e9506fed4657c9700eebdbec",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

클라이언트가 response 계산에 SHA-256 알고리즘을 사용하기로 선택하면, 클라이언트는 다음과 같은 Authorization 헤더 필드를 포함한 새 요청으로 응답합니다:

Authorization: Digest username="Mufasa",
    realm="http-auth@example.org",
    uri="/dir/index.html",
    algorithm=SHA-256,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    nc=00000001,
    cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
    qop=auth,
    response="753927fa0e85d155564e2e272a28d1802ca10daf449
       6794697cf8db5856cb6c1",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

3.9.2. SHA-512-256, 문자 인코딩 및 Userhash 예시

다음 예시는 GET 요청을 통해 보호된 문서를 요청한다고 가정합니다. 요청의 URI는 "http://api.example.org/doe.json"입니다. 클라이언트와 서버는 username의 해시(userhash)를 알고 있으며 UTF-8 문자 인코딩을 지원하고 SHA-512-256 알고리즘을 사용합니다. 요청에 사용되는 사용자 이름은 "Jason Doe"의 변형으로, 'a'는 실제로 유니코드 코드 포인트 U+00E4("LATIN SMALL LETTER A WITH DIAERESIS")이고 첫 번째 'o'는 U+00F8("LATIN SMALL LETTER O WITH STROKE")로, UTF-8 인코딩을 사용한 옥텟 시퀀스는 다음과 같습니다:

   J  U+00E4 s  U+00F8 n      D  o  e
   4A C3A4   73 C3B8   6E 20 44  6F 65

비밀번호는 "Secret, or not?"입니다.

클라이언트가 문서를 처음 요청할 때 Authorization 헤더 필드가 전송되지 않으므로 서버는 다음과 같이 응답합니다:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
    realm="api@example.org",
    qop="auth",
    algorithm=SHA-512-256,
    nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK",
    opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS",
    charset=UTF-8,
    userhash=true

클라이언트는 필요한 자격증명을 사용자에게 묻고 다음과 같은 Authorization 헤더 필드를 포함한 새 요청을 보낼 수 있습니다:

Authorization: Digest
    username="488869477bf257147b804c45308cd62ac4e25eb717
       b12b298c79e62dcea254ec",
    realm="api@example.org",
    uri="/doe.json",
    algorithm=SHA-512-256,
    nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK",
    nc=00000001,
    cnonce="NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v",
    qop=auth,
    response="ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d
       6c861229025f607a79dd",
    opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS",
    userhash=true

클라이언트가 어떤 이유로든 해시된 사용자 이름을 제공할 수 없다면, 다음과 같은 Authorization 헤더 필드를 사용해 요청을 시도할 수 있습니다:

Authorization: Digest
    username*=UTF-8''J%C3%A4s%C3%B8n%20Doe,
    realm="api@example.org",
    uri="/doe.json",
    algorithm=SHA-512-256,
    nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK",
    nc=00000001,
    cnonce="NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v",
    qop=auth,
    response="ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d
       6c861229025f607a79dd",
    opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS",
    userhash=false

4. 국제화 고려사항

챌린지에서 서버는 A1 생성 시(참조: Section 3.4.2) 및 사용자 이름 해싱 시(참조: Section 3.4.4) 사용자 에이전트가 사용하기를 기대하는 문자 인코딩을 표현하기 위해 대소문자 구분 없이 "charset" 인증 매개변수(SHOULD)를 사용해야 합니다.

허용되는 유일한 값은 대소문자를 구분하지 않고 일치시키는 "UTF-8"이며(참조: RFC2978 섹션 2.3) 이는 서버가 사용자 이름과 비밀번호를 유니코드 정규화 형식 C("NFC", 참조: RFC5198 섹션 3)으로 변환한 다음 UTF-8 문자 인코딩 스킴으로 옥텟으로 인코딩할 것으로 기대함을 나타냅니다(참조: RFC3629).

사용자 이름의 경우 수신자는 RFC7613 섹션 3.3에 정의된 "UsernameCasePreserved" 프로파일에 정의된 모든 문자를 지원해야 하며(MUST) 단, 콜론(" : ") 문자는 예외로 합니다.

비밀번호의 경우 수신자는 RFC7613 섹션 4.2에 정의된 "OpaqueString" 프로파일에 정의된 모든 문자를 지원해야 합니다(MUST).

사용자 에이전트가 서버가 표시한 인코딩을 지원하지 않으면 요청을 실패시킬 수 있습니다.

사용자 이름을 해시된 형태로 보낼 수 없고 비-ASCII 문자를 포함하는 경우, 클라이언트는 대신 username* 매개변수를 포함할 수 있습니다(값 인코딩은 RFC5987에 정의된 방식을 사용).

5. 보안 고려사항

5.1. 제한사항

사람이 기억하기 쉬운 비밀번호와 함께 사용할 때 HTTP 다이제스트 인증은 사전 공격(dictionary attack)에 취약합니다. 이러한 공격은 더 이상 안전하다고 간주되지 않는 알고리즘을 포함하여 널리 사용되는 어떤 암호학적 알고리즘에 대한 공격보다 훨씬 쉽습니다. 다시 말해, 알고리즘의 유연성만으로는 이러한 사용을 더 안전하게 만들지 못합니다.

따라서 다이제스트 인증은 합리적 수준의 엔트로피를 가진 비밀번호(예: 128비트 이상)와 함께만 사용되어야 합니다(SHOULD). 이러한 비밀번호는 일반적으로 사람이 암기할 수는 없지만 자동화된 웹 서비스에는 사용될 수 있습니다.

다이제스트 인증을 사용하는 경우 이는 HTTPS와 같은 안전한 채널을 통해 수행되어야 합니다(SHOULD, 참조: RFC2818).

5.2. 비밀번호 저장

다이제스트 인증은 인증 주체(보통 서버)가 주어진 realm과 연관된 "비밀번호 파일"에 사용자 이름과 비밀번호에서 파생된 일부 데이터를 저장하도록 요구합니다. 일반적으로 여기에는 username과 H(A1)의 쌍이 포함될 수 있으며, H(A1)는 앞에서 설명한 대로 사용자 이름, realm, 비밀번호의 다이제스트 값입니다.

이것의 보안적 함의는 비밀번호 파일이 유출되면 공격자는 해당 realm의 서버 문서에 즉시 접근할 수 있게 된다는 점입니다. 표준 UNIX 비밀번호 파일과 달리, 이 정보는 서버 realm의 문서에 접근하기 위해 복호화될 필요가 없습니다. 반면에 사용자의 비밀번호를 얻기 위해서는 복호화 또는 더 가능성이 높은 무차별 대입 공격이 필요합니다. 이것이 비밀번호 파일에 realm이 포함되어 저장되는 이유입니다. 즉, 하나의 다이제스트 인증 비밀번호 파일이 유출되더라도 동일한 사용자 이름과 비밀번호를 가진 다른 파일들이 자동으로 손상되는 것은 아니지만(단, 무차별 대입 공격에 노출됩니다).

이로 인해 두 가지 중요한 보안 결과가 있습니다. 첫째로, 비밀번호 파일은 암호화되지 않은 비밀번호를 포함하고 있는 것처럼 보호되어야 합니다. 왜냐하면 그 파일은 그 realm의 문서 접근 목적상 사실상 평문 비밀번호와 동일하게 작동하기 때문입니다.

둘째로, realm 문자열은 단일 사용자가 사용할 가능성이 있는 모든 realm 사이에서 고유해야 합니다(SHOULD). 특히 realm 문자열에는 인증을 수행하는 호스트의 이름을 포함하는 것이 SHOULD됩니다. 클라이언트가 서버를 인증하지 못한다는 점은 다이제스트 인증의 약점입니다.

5.3. 다이제스트 인증을 사용하는 클라이언트의 인증

다이제스트 인증은 예컨대 공개키 기반 메커니즘과 비교했을 때 강력한 인증 메커니즘을 제공하지 않습니다.

그러나 다이제스트 인증은 LDAP에 제안되었던 CRAM-MD5보다 상당히 강력합니다(참조: RFC4513RFC2195). 이는 훨씬 더 약한 Basic 메커니즘을 대체하기 위해 고안되었습니다.

다이제스트 인증은 실제 사용자 이름과 비밀번호 보호 외에는 기밀성 보호를 제공하지 않습니다. 요청과 응답의 나머지 부분은 도청자에게 노출될 수 있습니다.

다이제스트 인증은 양방향 메시지에 대해 제한된 무결성 보호만 제공합니다. "qop=auth-int" 메커니즘을 사용하면 WWW-Authenticate 및 Authorization 헤더 필드의 response 매개변수 값을 계산하는 데 사용되는 메시지의 일부가 보호됩니다(참조: Section 3.2). 그러나 대부분의 헤더 필드와 그 값은 중간자 공격의 일환으로 수정될 수 있습니다.

보안 HTTP 트랜잭션에 대한 많은 요구사항은 다이제스트 인증으로 충족될 수 없습니다. 이러한 경우에는 TLS가 더 적절한 프로토콜입니다. 특히, 기밀성 보호가 필요한 트랜잭션에는 다이제스트 인증을 사용할 수 없습니다. 그럼에도 불구하고 다이제스트 인증은 유용하고 적합한 많은 용도를 제공합니다.

5.4. 제한적 사용 논스 값

다이제스트 스킴은 응답 값 생성을 시드하기 위해 서버가 지정한 논스 값을 사용합니다(참조: Section 3.4.1). 예시 논스(참조: Section 3.3)에서 보이듯 서버는 논스를 특정 클라이언트, 특정 리소스, 제한된 기간 또는 사용 횟수 등으로 사용을 제한하도록 구성할 수 있으며(MAY), 이는 재생 공격에 대한 보호를 강화합니다(참조: Section 5.5). 그러나 논스를 생성하고 검사하는 방법은 성능 및 자원 영향이 있습니다. 예를 들어, 서버는 발행된 각 논스가 반환되었는지 여부를 기록하고 모든 응답의 Authentication-Info 헤더 필드에 next-nonce 매개변수를 보내 각 논스 값을 한 번만 사용하도록 허용할 수 있습니다. 이는 즉각적인 재생 공격을 방지하지만 논스 값 검사의 비용이 높고 파이프라인된 요청에서는 인증 실패를 일으킬 수 있습니다(아마도 stale 논스 표시를 반환). 또한 ETag와 같은 요청 특정 요소를 포함하면 논스 사용을 해당 리소스 버전으로 제한하고 파이프라인을 방해합니다. 따라서 부작용이 있는 메서드에는 유용할 수 있으나 그렇지 않은 경우 성능상 허용 불가능할 수 있습니다.

5.5. 재생 공격

다이제스트 인증에 대한 재생 공격은 단순한 GET 요청의 경우 보통 무의미합니다. 도청자가 재생으로 얻을 수 있는 유일한 문서는 이미 보았기 때문입니다. 이는 요청된 문서의 URI가 클라이언트 요청에서 다이제스트화되며 서버는 그 문서만 전달하기 때문입니다. 반면 Basic 인증에서는 도청자가 사용자의 비밀번호를 얻으면 그 비밀번호로 보호된 모든 문서에 접근할 수 있습니다.

따라서 일부 목적에서는 재생 공격에 대비할 필요가 있습니다. 좋은 다이제스트 구현은 여러 방법으로 이를 완화할 수 있습니다. 서버가 생성한 논스 값은 구현에 따라 다르지만, 만약 논스에 클라이언트 IP, 타임스탬프, 리소스 ETag 및 서버 비밀 키의 다이제스트를 포함한다면 재생 공격은 간단하지 않습니다. 공격자는 서버가 요청을 보낼 것으로 믿는 주소와 다른 주소로 문서를 전달하도록 서버를 속여야 하며, 타임스탬프가 만료되기 전의 기간에만 공격이 성공할 수 있습니다. 논스에 클라이언트 IP와 타임스탬프를 포함하면 상태를 유지하지 않는 구현이 가능해집니다.

재생 공격을 전혀 허용해서는 안 되는 응용에서는 서버가 일회용 논스 값을 사용하여 두 번째 사용을 허용하지 않도록 할 수 있습니다. 이는 서버가 논스 타임스탬프(및 그와 함께 구성된 다이제스트)가 만료될 때까지 사용된 논스 값을 기억해야 하는 오버헤드를 요구하지만 재생 공격으로부터 효과적으로 보호합니다.

구현은 POST 및 PUT 요청에서의 재생 공격 가능성에 특별한 주의를 기울여야 합니다. 서버가 일회용 또는 제한적 사용 논스를 사용하거나 "qop=auth-int"의 무결성 보호 사용을 요구하지 않는 한 공격자는 성공한 요청의 유효한 자격증명을 위조된 데이터나 다른 메시지 본문으로 재생할 수 있습니다. 무결성 보호를 사용하더라도 대부분의 헤더 필드 메타데이터는 보호되지 않습니다. 적절한 논스 생성 및 검사로 이전에 사용된 유효 자격증명의 재생에 대해 어느 정도 보호를 제공할 수 있지만, 섹션 5.8를 참조하십시오.

5.6. 다중 인증 방식으로 인한 약점

HTTP/1.1 서버는 401(Authenticate) 응답에 여러 챌린지를 반환할 수 있으며(MAY) 각 챌린지는 서로 다른 인증 스킴을 사용할 수 있습니다. 사용자 에이전트는 이해하는 가장 강력한 인증 스킴을 선택하고 그 챌린지를 기반으로 사용자에게 자격증명을 요청해야 합니다(MUST).

서버가 WWW-Authenticate 헤더 필드를 통해 인증 스킴의 선택지를 제공할 때, 최종 인증의 강도는 제공된 인증 스킴들 중 가장 약한 것의 강도에 의해 좌우됩니다. 다중 인증 스킴을 악용하는 특정 공격 시나리오에 대해서는 아래의 섹션 5.7을 참조하십시오.

5.7. 온라인 사전 공격

공격자가 도청할 수 있다면, 도청한 논스/응답 쌍을 공통 단어 목록과 대조하여 테스트할 수 있습니다. 이러한 목록은 보통 가능한 모든 비밀번호 수보다 훨씬 작습니다. 각 비밀번호에 대해 응답을 계산하는 비용은 챌린지마다 한 번씩만 발생합니다.

서버는 사용자가 사전에 있는 비밀번호를 선택하지 못하도록 하여 이 공격을 완화할 수 있습니다.

5.8. 중간자 공격

다이제스트 인증은 악의적이거나 손상된 프록시와 같은 중간자(MITM) 공격에 취약합니다. 이는 도청의 모든 문제를 야기할 뿐만 아니라 공격자에게 추가 기회를 제공합니다.

가능한 MITM 공격 중 하나는 선택지에 약한 인증 스킴을 추가하여 클라이언트가 사용자 자격증명을 노출시키는 스킴을 사용하도록 유도하는 것입니다. 이러한 이유로 클라이언트는 제공된 선택지 중 자신이 이해하는 가장 강력한 스킴을 항상 사용해야 합니다(SHOULD).

더 악질적인 MITM 공격은 제공된 모든 선택지를 제거하고 Basic 인증만 요청하는 챌린지로 대체한 다음, 얻은 평문 자격증명을 사용해 원래 서버에 대해 더 강한 스킴으로 인증하는 것입니다. 특히 공격자가 '무료' 프록시 캐싱 서비스를 제공하여 이용자를 속이는 방식이 위험합니다.

사용자 에이전트는 자격증명 요청 시 어떤 인증 스킴이 사용되는지 시각적으로 표시하거나, 서버가 요청한 가장 강력한 인증 스킴을 기억해 약한 스킴 사용 전에 경고를 표시하는 등의 조치를 고려해야 합니다. 특정 사이트나 일반적으로 다이제스트 인증을 요구하도록 구성하는 것도 좋은 방안일 수 있습니다.

또는 악의적 프록시는 클라이언트를 공격자가 원한 요청이 아니라 다른 요청을 하도록 위조할 수 있습니다. 물론 이는 Basic 인증에 대한 유사 공격보다 여전히 더 어렵습니다.

5.9. 선택 평문 공격

다이제스트 인증에서는 MITM이나 악의적 서버가 클라이언트가 응답을 계산할 때 사용할 논스를 임의로 선택할 수 있습니다. 이를 "선택 평문" 공격이라 부릅니다. 논스를 선택할 수 있는 능력은 암호분석을 훨씬 쉽게 만듭니다.

그러나 선택 평문을 사용하여 다이제스트에서 사용된 일방향 함수들을 분석하는 방법은 현재 알려져 있지 않습니다.

이 공격에 대한 대응책은 클라이언트가 cnonce 매개변수를 사용하는 것입니다; 이렇게 하면 클라이언트가 해시에 대한 입력을 공격자가 선택하지 못하는 방식으로 변화시킬 수 있습니다.

5.10. 사전(미리 계산된) 공격

다이제스트 인증에서 공격자가 선택 평문 공격을 실행할 수 있다면, 공격자는 자신의 선택에 따른 논스에 대해 많은 일반 단어들의 응답을 미리 계산하고 응답/비밀번호 쌍의 사전을 저장할 수 있습니다. 이러한 미리 계산은 종종 여러 대의 기계에서 병렬로 수행될 수 있습니다. 그런 다음 공격자는 선택 평문 공격을 사용해 해당 챌린지에 대응하는 응답을 획득하고 단순히 사전에서 비밀번호를 찾아낼 수 있습니다. 대부분의 비밀번호가 사전에 없더라도 일부는 있을 수 있습니다. 공격자가 챌린지를 선택할 수 있기 때문에, 목록의 각 비밀번호에 대한 응답 계산 비용을 많은 비밀번호들에 대해 분산시킬 수 있습니다. 1억 개의 비밀번호/응답 쌍을 가진 사전은 약 3.2GB의 디스크 저장 공간을 필요로 합니다.

이 공격에 대한 대응책은 클라이언트가 cnonce 매개변수를 사용하는 것입니다.

5.11. 일괄 무차별 대입 공격

다이제스트 인증에서 MITM은 선택 평문 공격을 실행하여 동일한 논스에 대해 여러 사용자의 응답을 수집할 수 있습니다. 그런 다음 단일 패스에서 해당 논스/응답 쌍들 가운데 하나를 생성하는 모든 비밀번호의 부분집합을 찾을 수 있습니다. 또한 첫 번째 비밀번호를 찾는 시간을 수집한 논스/응답 쌍의 개수만큼 줄일 수 있습니다. 이 비밀번호 공간 탐색은 종종 여러 기계에서 병렬로 수행될 수 있으며, 심지어 단일 기계도 여섯 글자 이하의 모든 비밀번호를 몇 시간 내에 검색할 수 있다는 보고가 있습니다.

이 공격에 대한 대응책은 클라이언트가 cnonce 매개변수를 사용하는 것입니다.

5.12. 매개변수 무작위성

이 프로토콜의 보안은 클라이언트 및 서버 논스와 같은 임의로 선택된 매개변수의 무작위성에 크게 의존합니다. 이러한 값들은 강력한 랜덤 소스 또는 적절히 시드된 의사난수 소스에 의해 생성되어야 합니다(참조: RFC4086).

5.13. 요약

현대 암호학적 기준으로 볼 때 다이제스트 인증은 약합니다. 그러나 광범위한 목적에 대해 Basic 인증을 대체하는 유용한 수단입니다. Basic 인증의 일부 약점을 완화하지만 모든 약점을 해결하지는 못합니다. 그 강도는 구현에 따라 달라질 수 있습니다. 특히 논스의 구조(서버 구현에 따라 다름)는 재생 공격을 시도하기의 난이도에 영향을 줄 수 있습니다. 일부 구현은 재생 가능성을 제거하기 위해 일회용 논스나 다이제스트를 사용하는 서버 오버헤드를 감수할 수 있고, 다른 구현은 앞에서 권장한 것과 유사한 제한된 논스를 사용하거나 제한된 수명으로 만족할 수 있습니다.

결론적으로, 어떤 준수 구현이라도 암호학적 기준으로는 상대적으로 약하지만, 어떤 준수 구현이든 Basic 인증보다 훨씬 우수합니다.

6. IANA 고려사항

6.1. HTTP 다이제스트 인증을 위한 해시 알고리즘

이 명세는 기존의 "Hypertext Transfer Protocol (HTTP) Digest Algorithm Values" 범주 아래에 "Hash Algorithms for HTTP Digest Authentication"이라는 새로운 IANA 레지스트리를 생성합니다. 이 레지스트리는 HTTP 다이제스트 인증에서 사용할 수 있는 해시 알고리즘을 나열합니다.

새 해시 알고리즘을 등록할 때 다음 정보는 제공되어야 합니다(MUST):

Hash Algorithm

  • 해시 알고리즘의 텍스트 이름.

Digest Size

  • 알고리즘 출력의 크기(비트).

Reference

  • 이 레지스트리에 알고리즘을 추가하는 명세에 대한 참조.

이 레지스트리의 업데이트 정책은 Specification Required입니다(참조: RFC5226).

초기 레지스트리는 다음 항목들을 포함합니다:

Hash Algorithm Digest Size Reference
"MD5" 128 RFC 7616
"SHA-512-256" 256 RFC 7616
"SHA-256" 256 RFC 7616

레지스트리에 정의된 각 알고리즘은 예를 들면 MD5-sess, SHA-256-sess 등과 같이 "-sess" 변형을 가질 수 있습니다.

기존의 "HTTP Digest Algorithm Values" 레지스트리의 목적을 명확히 하고 두 레지스트리 간의 혼동을 피하기 위해, IANA는 기존 레지스트리에 다음 설명을 추가했습니다:

  • 이 레지스트리는 RFC 3230에 명시된 바와 같이 HTTP 메시지 본문의 다이제스트를 생성할 때 사용할 수 있는 알고리즘들을 나열합니다.

6.2. 다이제스트 스킴 등록

이 명세는 "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry"의 Digest 스킴 기존 항목을 업데이트하고 이 명세에 대한 새 참조를 추가합니다.

  • Authentication Scheme Name: Digest
  • Pointer to specification text: RFC 7616

7. 참고 문헌

7.1. 규범 참조

[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.
[RFC2978]
Freed, N. and J. Postel, “IANA Charset Registration Procedures”, BCP 19, RFC 2978, DOI 10.17487/RFC2978, October 2000, <http://www.rfc-editor.org/info/rfc2978>.
[RFC3629]
Yergeau, F., “UTF-8, a transformation format of ISO 10646”, STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <http://www.rfc-editor.org/info/rfc3629>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <http://www.rfc-editor.org/info/rfc3986>.
[RFC4086]
Eastlake 3rd, D., Schiller, J., and S. Crocker, “Randomness Requirements for Security”, BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, <http://www.rfc-editor.org/info/rfc4086>.
[RFC5198]
Klensin, J. and M. Padlipsky, “Unicode Format for Network Interchange”, RFC 5198, DOI 10.17487/RFC5198, March 2008, <http://www.rfc-editor.org/info/rfc5198>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.
[RFC5987]
Reschke, J., “Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters”, RFC 5987, DOI 10.17487/RFC5987, August 2010, <http://www.rfc-editor.org/info/rfc5987>.
[RFC6454]
Barth, A., “The Web Origin Concept”, RFC 6454, DOI 10.17487/RFC6454, December 2011, <http://www.rfc-editor.org/info/rfc6454>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, June 2014, <http://www.rfc-editor.org/info/rfc7230>.
[RFC7231]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, DOI 10.17487/RFC7231, June 2014, <http://www.rfc-editor.org/info/rfc7231>.
[RFC7234]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Caching”, RFC 7234, DOI 10.17487/RFC7234, June 2014, <http://www.rfc-editor.org/info/rfc7234>.
[RFC7235]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Authentication”, RFC 7235, DOI 10.17487/RFC7235, June 2014, <http://www.rfc-editor.org/info/rfc7235>.
[RFC7613]
Saint-Andre, P. and A. Melnikov, “Preparation, Enforcement, and Comparison of Internationalized Strings Representing Usernames and Passwords”, RFC 7613, DOI 10.17487/RFC7613, August 2015, <http://www.rfc-editor.org/info/rfc7613>.
[RFC7615]
Reschke, J., “HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields”, RFC 7615, DOI 10.17487/RFC7615, September 2015, <http://www.rfc-editor.org/info/rfc7615>.

Appendix A. RFC 2617에서의 변경사항

이 문서는 다음과 같은 변경사항을 도입합니다:

  • 두 개의 새로운 알고리즘 지원 추가: SHA2-256(필수 구현) 및 SHA2-512/256(백업), 그리고 적절한 알고리즘 협상 정의. 문서는 하위 호환성을 위해 MD5 알고리즘 지원을 유지합니다.
  • 개인정보 보호를 위해 사용자 이름 해싱 기능 및 관련 매개변수 도입.
  • A1 계산과 사용자 이름 및 비밀번호 인코딩에 영향을 주는 다양한 국제화 고려사항 추가.
  • HTTP 다이제스트 인증에서 사용할 수 있는 해시 알고리즘을 나열하는 새로운 IANA 레지스트리 "Hash Algorithms for HTTP Digest Authentication" 도입.
  • RFC 2069과의 하위 호환성 폐기.

Appendix B. 감사의 글

다이제스트 메커니즘과 그 동작에 대한 완전한 설명을 제공하기 위해, 이 문서는 많은 부분을 RFC2617에서 차용했습니다. 이 문서의 저자들은 해당 명세 작업에 기여한 John Franks, Phillip M. Hallam-Baker, Jeffery L. Hostetler, Scott D. Lawrence, Paul J. Leach, Ari Luotonen, 그리고 Lawrence C. Stewart에게 감사를 표합니다.

특별히 이 문서의 여러 부분에 대해 많은 검토, 의견, 제안 및 텍스트를 제공한 Julian Reschke에게 감사드립니다.

저자들은 또한 Stephen Farrell, Yoav Nir, Phillip Hallam-Baker, Manu Sporny, Paul Hoffman, Yaron Sheffer, Sean Turner, Geoff Baskwill, Eric Cooper, Bjoern Hoehrmann, Martin Durst, Peter Saint-Andre, Michael Sweet, Daniel Stenberg, Brett Tate, Paul Leach, Ilari Liusvaara, Gary Mort, Alexey Melnikov, Benjamin Kaduk, Kathleen Moriarty, Francis Dupont, Hilarie Orman, 및 Ben Campbell에게 정성 어린 검토와 의견에 대해 감사를 표합니다.

저자들은 또한 이 문서의 다양한 측면을 논의할 때 메일링 리스트에서 의견을 준 Jonathan Stoke, Nico Williams, Harry Halpin, 및 Phil Hunt에게 감사를 표합니다.

저자들은 또한 이 문서의 일부 측면에 대한 신중한 검토와 피드백을 준 Paul Kyzivat 및 Dale Worley에게 감사를 표합니다.

저자들은 레지스트리 관련 도움을 준 Barry Leiba에게 감사를 표합니다.

저자 주소

Rifaat Shekh-Yusef (editor)
Avaya
250 Sidney Street
Belleville, Ontario
Canada
Phone: +1-613-967-5267
EMail: rifaat.ietf@gmail.com
David Ahrens
Independent
California
United States
EMail: ahrensdc@gmail.com
Sophie Bremer
Netzkonform
Germany
EMail: sophie.bremer@netzkonform.de