Network

HTTP The Definitive Guide - 13. Digest Authentication

깡구_ 2022. 12. 12. 22:29

title: HTTP The Definitive Guide - 13. Digest Authentication
date: 2022-12-12
tags:

  • Network
  • HTTP



Introduction

HTTP The Definitive Guide



GDSC에서 해당 서적을 통해 HTTP를 공부하는 스터디에 참가하고 있다.
HTTP 이전의 내용은 개인적으로 공부하며 채울 예정이다.
이번 Chapter는 13장 Digest Authentication 이다.


Purpose

Digest Authentication에 대해 알아본다.


The Improvement of Digest Authentication

기존의 Basic Authentication에서 발생하는 보안 문제를 해결하기 위해 Digest Authentication이 고안되었다.
Digest Authentication은 아래와 같은 동작을 통해 보안 문제를 해결한다.

  • Secret Password는 완벽하게 안전한 Network가 아니라면 절대 전송하지 않는다.
  • Authentication Handshake 과정을 탈취당하는 것을 막는다.
  • 선택적으로 Message 조작을 막는다.
  • 일반적인 공격을 막는다.

이러한 방식을 도입하더라도, Digest Authentication은 보안 문제에서 완전히 자유롭지 않다.
공개키 암호화와 같은 방식보다 덜 안전하며, Password와 같은 중요한 정보만 보호한다.
더 안전한 방식을 원한다면 TLS (Transport Layer Security)나 HTTPS (Secure HTTP)가 더 적합할 것이다.
이 때문인지 현재 Digest Authentication은 표준에서 아예 제외되었으며, 거의 사용하지 않는 것으로 알고 있다.

현재 사용하지 않음에도 이를 공부하는 이유는 간단하다. HTTP의 발전과 함께 보안 문제를 해결하는 과정을 파악하기 위해서이다.
또한 Digest는 Hash Function의 일부이며, Digest만 이용하지는 않더라도 Digest를 함께 이용하는 기법은 많이 존재한다.

Using Digest to Keep Password Secret

Digest Authentication

Digest Authentication의 Motto는 Network를 통해 Password를 절대 보내지 않는다. 이다.
대신 복호화가 어려운 암호화된 Fingerprint나 Digest를 전송한다.
Client와 Server는 기존 Password를 알고 있기에 올바른 정보인지 판단하기 쉬우나 복호화가 어렵기에 조금 더 안전하다.
위 그림은 Digest Authentication 과정이다.
4개의 Phase는 동일하나, Password 전송 시 Digest를 이용하는 것만 차이가 있다.

One-Way Digest

MD5 Digest

Digest는 정보의 요약으로, Hash Function의 결과로 나온 데이터가 Digest이다.
당연하게도 Collision이 발생할 수 있으나, 실제로 Collision이 발생할 가능성이 매우 낮기에 이를 감안하고 사용한다.
MD5는 Message Digest #5로, 주어진 데이터를 128Bits로 변환하여 16진수로 표시한다.

Using Nonce to Prevent Replay

Digest를 통해 Password를 안전하게 Server로 전송할 수 있으나, 보안 문제는 여전히 남아있다.
물론 Digest로 인하여 기존의 Password를 알아내는 것은 매우 어려우나, Digest를 그대로 이용하면 Replay Attack이 가능하다.
이를 해결하기 위해 Nonce라는 Token을 추가로 이용한다.
Nonce는 Digest를 만들 때 사용되는 Token으로, 매우 작은 시간 혹은 매 Authentication마다 바뀌는 값이다. 난수 생성을 위한 Seed 값이라고 볼 수 있다.
Nonce를 이용하기에 동일한 데이터에 대한 Digest는 계속하여 바뀌게 되므로 Replay Attack을 방지할 수 있다.
Nonce는 Challenge Phase의 WWW-Authenticate Header에 담겨 Client로 전송된다.

Digest Authentication Handshake

Digest Authentication Handshake

Digest Authentication에는 기존 Header에 새로운 Option이 추가되며, Authorization-Info라는 새로운 Optional Header가 추가되었다.

위 그림에서는 Request Phase는 이미 진행되었으며, 이후의 Challenge Phase로 시작한다.
Challenge Phase에서 Server는 Nonce를 계산하여 WWW-Authenticate Header에 이를 포함한다. 이때 Server에서 지원하는 Digest Algorithm도 함께 알려준다.
Client는 Server가 지원하는 Digest Algorithm 중 하나를 선택하며, Nonce와 함께 이용하여 중요 정보에 대한 Digest를 계산한다.
이때 Client에서 Server가 올바른 Server인지 확인할 수 있다. Client-Nonce를 생성하여 Authorization Phase의 Request에 이를 함께 보낸다.
Server는 Digest를 확인하여 Client를 식별한다. Client가 Server 식별을 원할 경우, Client-Node를 이용하여 rspauth (Response Auth)를 생성한다.
다음에 사용할 Nonce를 미리 생성할 수 있으며, 이와 함께 rspauth를 전송한다. Client는 rspauth를 확인하여 Server를 식별한다.

Basic Authentication vs Digest Authentication

위 그림은 Basic Authentication과 Digest Authentication의 차이를 알려주는 그림이다.

Digest Calculation

Digest 계산은 Public 정보와 Secret 정보, 그리고 Nonce 값을 조합하여 만들어진다.
Digest 계산 방법에 대해 자세히 알아본다.

Input Data

Digest 계산에는 3가지 요소가 필요하다.

  • Hash 함수 H(d)와 Digest 함수 KD(s,d), s는 Secret이며 d는 Data이다.
  • A1 - 암호와 같은 Secret 정보를 포함한 데이터
  • A2 - Request Message와 같이 Nonsecret 정보를 포함한 데이터

A1과 A2는 H 함수와 KD 함수를 통해 생성된다.

Algorithm H(d) and KD(s,d)

Digest Authentication은 다양한 Digest Algorithm을 지원하며, RFC 2617에서 MD5와 MD5-sess가 제안되었다.
현재 MD5는 보안 이슈가 존재하여 암호화에 권장되는 Algorithm은 아니지만, 문제가 발견되기 전에는 표준으로 자리 잡았다.
MD5와 MD5-sess 모두 사용될 경우, H(d)는 MD5를 이용하며 KD(s,d)는 <s>:<d> 로 이은 후 MD5를 이용한다.

The Security-Related Data (A1)

A1 Algorithm Using MD5 and MD5-sess

A1은 중요한 Secret 정보를 포함한 데이터이다.
MD5를 이용할 경우, 위와 같이 묶은 후 MD5를 이용한다.
MD5-sess를 이용할 경우, 우선 위와 같이 MD5를 이용한 후 뒤에 nonce를 붙인다.

The Message-Related Data (A2)

A2 Algorithm

A2는 Message와 같이 Nonsecret 정보를 포함한 데이터이다. qop가 무엇이냐에 따라 A2가 정해진다.
request-method는 HTTP Method를 의미한다.
uri-directive-value는 *, 절대 URL, 절대 경로 등을 이용할 수 있으나 Request URI와 일치하여야 한다.
Request URI가 절대 URL일 경우, uri-directive-value 또한 절대 URL이어야 한다.

Overall Digest Algorithm

Old and New Digest Algorithm

RFC 2617에서 제안한 Digest Algorithm은 크게 두 가지로 나눌 수 있다.

  • 과거의 RFC 2069와 호환이 되며, qop Option이 없을 경우 사용한다.
  • 당시 사용하던 Digest Algorithm으로, nonce를 포함하여 이용한다.

Digest Authentication Session

우선 Protection Space라는 용어가 등장하는데, 아래에서 자세하게 설명한다.
간단하게 말하자면 Resource마다 인증 방법과 권한이 다를 수 있다. 같은 것들은 같은 Protection Space에 존재한다.

Client가 Protection Space에서 WWW-Authenticate에 대한 Response를 할 때 Authentication Session이 시작된다.
해당 Session은 Client가 해당 Protection Space에서 또 다른 WWW-Authenticate Request를 받을 때까지 유지된다.
Client는 Authorization Header를 작성하기 위해 이름, 비밀번호, Nonce, Nonce Count, 노출되지 않는 값 등을 기억하여야 한다.
Nonce가 파기되더라도 Server는 오래된 Authorization 정보를 받아들이고 Session을 유지할 수 있다.
엄격한 Server라면 Status Code 401과 새로운 Nonce를 Response하여 재인증을 요청할 수도 있다.

Preemptive Authorization

Preemptive Authorization

일반적인 Authentication에서는 Transaction 전에 Request & Challenge Phase가 진행된다.
다음에 사용될 Nonce가 바뀌기에 Request Phase와 Challenge Phase가 불필요하게 반복된다.
다음에 사용할 Nonce를 알 수 있다면 Client는 바로 Authorization Phase로 넘어갈 수 있으며, 보다 빠른 통신이 가능하다.

다만 Nonce는 Replay Attack을 막기 위해 도입된 기술로, Client가 Request Phase를 진행하지 않는다면 Nonce를 알아낼 수 없다.
이를 해결하기 위한 세 가지 방법이 존재한다.

  • Server가 Success Phase에서 다음에 사용할 Nonce를 미리 보낸다.
  • Server가 짧은 시간 동안의 동일한 Nonce 재사용을 허용한다.
  • Client와 Server의 시간 동기화 작업을 통해 다음에 사용할 Nonce를 계산할 수 있도록 한다.

 

Next Nonce Pregeneration

Server가 Success Phase에서 Status Code 200과 함께 다음에 사용할 Nonce를 보내는 방법이다.

  • Authentication-Info: nextnonce="<nonce-value>"

Success Phase를 진행할 경우 다음 인증 과정이 짧아진다는 장점이 존재한다.
다만 서적 집필 시기에는 HTTP 1.1이 최신의 표준이었으며, 2.0에서 Pipelining을 도입하기 위해 노력하던 중이었기에 Pipelining이 도입이 되면 사용이 어려운 방법이었다.

Limited Nonce Reuse

Server에서 특정 시간 동안 Nonce 재사용 횟수를 정하는 방법이다.
Client는 기존에 사용하던 Nonce를 이용하다가, Nonce를 재사용하지 못할 경우 Server는 Status Code 401을 Response하여 Challenge Phase로 돌아간다.

이 방식은 동일한 Nonce를 재사용할 수 있기에 Replay Attack의 위험이 더 커진다.
Counter나 IP Address 등을 이용하여 Replay Attack을 어렵게 만들 수는 있으나, Nonce 재사용이라는 취약점은 여전히 남는다.

Synchronized Nonce Generation

Secret Key를 교환하여 시간 동기화 작업을 진행한 Nonce 생성 Algorithm을 이용할 수 있다.
이는 Digest Authentication 규격에서 벗어나 더 이상 다루지 않는다.

Nonce Selection

RFC 2617에서 제시된 Nonce 생성 공식은 아래와 같다.

  • BASE64(time-stamp H(time-stamp ":" ETag ":" private-key))

time-stamp는 Server의 시각이거나 반복되지 않는 수다.
Server는 Client에서 사용한 Nonce를 확인하며, 해당 Nonce가 파기되었다면 인증이 실패한다.
Server는 Nonce의 유효 시간을 제한할 수 있다.

ETag는 HTTP ETag Header이다.
이를 이용하여 Version이 다를 경우, 동일한 Digest를 이용한 Request를 금지할 수 있다.

private-key는 Server만 알 수 있는 데이터이다.

Server에서는 이전에 사용한 Nonce나 Digest 재사용을 허용할 수도 있다.
POST나 PUT Method의 경우 일회용 Nonce나 Digest를 사용하도록 할 수 있다.
GET Method의 경우 time-stamp를 이용하도록 할 수 있다.

Nonce 선택에 따른 실질적인 보안의 경우 본 Chapter의 마지막에 다룬다.

Symmetric Authentication

Request and Response Digest

RFC 2617이 제안되면서 Client도 Client에서 생성한 Nonce를 Server에 넘겨주어 인증을 요청할 수 있다.
선택적인 Option이지만, 보안에 큰 영향을 주기에 Client와 Server 양쪽에 모두 구현하기를 권장하였다고 한다.
Symmetric Authentication은 qop가 명시되었을 경우에만 진행이 된다.
다만 Response Digest는 Request Method가 존재하지 않기에 계산하는 방식은 위 그림과 같이 다르다.

Quality of Protection Enhancement

qop Field 덕분에 Client와 Server는 같은 qop Option을 사용한다.
qop Field는 WWW-Authenticate, Authorization, Authentication-Info 3가지 Header에 존재할 수 있다.
RFC 2069 이전에 구현된 것과의 호환성을 위해 qop를 사용하지 않을 수도 있으나, 당시 최신의 Digest 구현에서는 지원되어야 한다.

Message Integrity Protection

Integrity Protection이 적용될 경우 (qop="auth-init"), Hash는 Message Body가 아닌 Entity Body이다.
이는 Encoding이 적용되지 않았을 때 계산이 된다.

Digest Authentication Header

Basic Authentication과 Digest Authentication 모두 Challenge Phase와 Response Phase에 적절한 Header를 가진다.
Digest Authentication은 인증 이후 Authorization-Info Header를 추가로 가질 수 있다.
이는 다음에 사용할 Nonce를 알려주기 위해 사용되며, 서적에는 Header에 대한 자세한 내용이 나와 있으나 생략한다.

Practical Consideration

Digest Authentication에서 고려해야 할 점이 몇 가지 존재한다.

Multiple Challenge

Server는 여러 Challenge Phase를 요청할 수 있다.
Client가 어떠한 Authentication을 사용하는지 모를 경우, Basic Authentication과 Digest Authentication 모두 요청할 수 있다.
이 경우 Client는 제시된 방법 중 사용 가능하며 가장 강력한 Authentication 기법을 이용한다.
또한 WWW-Authenticate Header나 Proxy-Authenticate Header가 여러 개 제공되거나 많은 Challenge가 들어올 경우, 이를 분석할 때 유의하여야 한다.
이처럼 여러 Authentication을 사용 가능할 때, Weakest Link 문제가 발생할 수 있다.

Error Handling

Digest Authentication에서 잘못된 값이나 요청한 Directive가 존재하지 않는다면 Status Code 400을 Response해야 한다.
잘못된 Response로 로그인에 실패하면 Logging을 해야 하며, 공격의 가능성이 존재한다.
uri에 의해 명시된 Resource가 실제 Resource와 동일한지 확인해야 하며, 다르다면 Status Code 400을 Response해야 한다.
Proxy가 중간에 가로채어 Request를 변경하는 문제를 방지하기 위한 목적이다.

Protection Space

위에서 나온 Protection Space이다.
Realm을 이용하여 Resource에 다른 인증 체계와 권한을 부여하여 이용할 수 있다.
동일한 인증 체계와 권한을 이용하는 것들은 같은 Protection Space에 있다고 볼 수 있다.
어떤 Protection Space에 대한 인증이 완료된 후, 일정 시간 동안 동일한 Protection Space의 다른 Resource 접근 시 인증에 사용한 정보를 재사용할 수도 있다.
Protection Space를 구분하는 방식은 아래와 같다.

  • Basic Authentication - Client는 모든 URI나 Request에 사용한 URI의 하위 영역을 같은 Protection Space로 가정한다. 이때 Server의 추가적인 인증이 없다면 인증 정보를 재사용한다.
  • Digest Authentication - Challenge Phase의 WWW-Authenticate Header의 Domain Field에서 Protection Space를 상세하게 명시한다. 해당 Field에서 명시한 URI와 하위 영역을 같은 Protection Space로 가정하고 이용한다. Domain Field가 없거나 비어있다면 모든 URI는 같은 Protection Space에 있다고 가정한다.

 

Rewriting URI

Proxy는 아래의 경우, URI를 재작성할 수 있다. 이때 Resource의 명칭은 달라질 수도 있다.

  • Hostname을 Normalize하거나 IP Address로 대체한다.
  • Embedded Character를 %를 이용한 Escape Form으로 대체한다.
  • Resource를 가져오는 데에 영향을 주지 않는 추가적인 Attribute의 경우, URI에 붙이거나 중간에 삽입할 수도 있다.

Proxy가 URI를 재작성할 수 있으며 Sanity Check가 이루어지기에 이렇게 변경이 될 경우 Digest Authentication이 중단된다.

Cache

Shared Cache에서 Authorization Header를 포함한 Request를 받고 해당 Request에 대한 Response가 존재할 경우, 아래 두 가지 Cache-Control Directive가 존재할 경우에만 Cache에서 바로 Response할 수 있다.

  • must-revalidate Directive가 존재할 경우, 우선 Server에 Request하여 Response를 확인한 후 Response한다. Server에서 새로운 Request에 대해 인증을 확인할 수 있도록 하는 것이다.
  • public Directive가 존재할 경우, Response가 가능하다.

 

Security Consideration

RFC 2617에서는 HTTP Authentication에서 발생하는 보안 문제를 요약하기도 하였다. 그중 일부를 다룬다.

Header Tampering

Header Tampering 없이 이용 가능한 System 제공을 위해 end-to-end Encryption이나 Digital Signature, 둘 모두를 이용한다.
Digest Authentication은 WWW-Authenticate Header와 Authorization Header에 대한 보안은 어느 정도 갖추더라도, 이외의 정보에 대한 보안 취약점은 존재한다.

Replay Attack

인증에 사용한 정보를 중간에 가로채 그대로 이용하는 공격이다.
GET Method를 가로채어 PUT이나 POST Method로 이용하여 Server를 공격할 수도 있다.
Client의 IP Address, Time-stamp, ETag, Server의 Private Key 등을 포함한 Nonce를 이용하면 공격을 어느 정도 방지할 수 있다.
이 중 Client의 IP Address를 이용하는 것은 Proxy를 거치거나 IP Spoofing 등의 문제가 여전히 발생한다.
일정 시간 동안만 인증에 사용 가능한, 각 Transaction마다 새로운 Nonce를 만들면 Replay Attack을 거의 완벽하게 막을 수 있다.
다만 Preemptive Authorization에서 말했듯이 Phase의 반복으로 인하여 Server의 부하가 증가하는 문제가 남아있다.

Multiple Authentication Mechanism

Server가 여러 Authentication을 지원할 때, WWW- Authenticate Header를 통해 선택하는 편이다.
Client에서 지원하는 방법이 다를 수 있기에, 결과적으로 가장 약한 Authentication 방법이 보안 강도라고 생각하면 된다.
이 문제를 최대한 줄이기 위해서는 Client가 가장 강한 방법을 선택하는 것이다.
이 방법이 어렵다면 Proxy를 이용하여 가장 강력한 Authentication을 이용하는 것이나, 모든 Client에서 이를 지원할 수 있어야만 가능하다.

Dictionary Attack

유저의 Password를 추측하는 공격이다.
유저가 간단한 Password를 이용하고 Server에서 간단한 Nonce를 이용한다면 찾아내기 쉽다.
Password Aging 정책이 없고 시간과 자원만 충분하다면 언젠가는 보안을 뚫을 수 있다.
이를 막을 완벽한 방법은 없다. 그저 Server는 어려운 Nonce를 사용하고 유저는 복잡하여 쉽게 알아내기 어려운 Password를 사용하는 것이다.

Hostile Proxy and Man-in-the-Middle Attack

대부분의 Internet Traffic은 Proxy를 거친다. 다양한 기법의 도입으로 유저는 Proxy의 존재를 모르더라도, 사실 Proxy를 거치는 경우가 매우 많다.
일부 Proxy가 악의적인 목적으로 존재할 경우, 중간자 공격의 위험이 존재한다.
이 경우 가장 약한 Authentication으로 대체하여 이용하는 경우가 많다.
Extension Interface를 이용하면 신뢰 가능한 Proxy를 손상시킬 수 있다.
Proxy는 가끔 정교한 Programming Interface를 제공하며, Plugin을 이용하여 이러한 Proxy에게서 Traffic을 가로채거나 수정할 수 있다.
물론 Proxy가 제공하는 보안이나 데이터 센터 보안으로 인하여 Plugin을 이용한 중간자 공격의 가능성을 크게 낮춘다.
이러한 중간자 공격을 완벽하게 막을 방법은 없다.
Authentication 강도를 확인할 수 있는 시각적 단서나 가장 강력한 Authentication을 이용하면 공격을 어느 정도 막을 수 있으나, 여전히 문제는 남아있다.
집필 당시 이를 해결하기 위한 유일한 방법은 SSL을 이용하는 것이었다.

Chosen Plaintext Attack

Client는 Server가 넘겨주는 Nonce를 이용하지만, 이를 중간에 가로채 잘못된 Nonce를 알려주는 방법도 존재한다.
이러한 공격을 Chosen Plaintext Attack이라고 하며, 몇 가지 변형된 방식이 존재한다.

  • Precomputed Dictionary Attack - Dictionary Attack과 결합한 공격이다. 잘못된 Nonce를 알려주며, Client가 보낸 Digest에 Dictionary Attack을 이용하여 Password를 찾는다.
  • Batched Brute-Force Attack - 가능한 모든 암호를 시도하여 찾는 공격이다. 컴퓨터의 성능이 발전함에 따라 이러한 공격은 더욱 쉬워진다.

큰 문제라고 생각이 되나, 이는 쉽게 막을 수 있다.
Client는 선택적인 cnonce Directive를 이용하여 Digest를 생성한다.
복잡한 Password와 Password Aging 정책과 결합하여 공격을 완벽하게 막아낼 수 있다.

Storing Password

Digest Authentication은 Server가 저장한 Password와 비교한다.
이때 Server의 Digest Authentication Password File이 손상되면 복호화 없이 Password 갈취가 가능하다.
이를 막는 방법은 다음과 같다.

  • 해당 File을 평문의 Password를 저장하는 것처럼 보호한다.
  • File 손상에 대비하여 특정 영역에서만 피해가 가도록 Realm 이름을 구분한다. Host와 Domain 이름이 포함된 정규화된 Realm 이름은 이를 만족해야 한다.

Digest Authentication은 일부 정보만 보호한다. 진정한 보안 Transaction은 SSL로만 가능하며, 이는 다음 Chapter에서 다룬다.

Conclusion

Digest Authentication에 대해 자세히 알아보았다.
현재 거의 이용하지 않지만, 이를 도입한 이유와 발생하는 문제들에 대해 파악할 수 있었다.
Digest Algorithm은 유익한지 모르겠으나, 보안 이슈의 경우 생각보다 많은 것들을 알 수 있었다.