Digest

개요

Digest 인증(RFC 7616)은 비밀번호를 평문이나 Base64로 그대로 보내지 않기 위해 만들어진 챌린지-응답 방식입니다. 서버가 nonce(일회성 값)를 던지면 클라이언트는 사용자 이름·비밀번호·nonce·요청 메서드·URI를 해시해 그 결과(response)만 전송하므로, 네트워크에 비밀번호 원문이 흐르지 않습니다.

전송 방식

Authorization: Digest username=..., realm=..., nonce=..., uri=..., response=...

자세히

흐름은 이렇습니다. 첫 요청에 서버가 401과 함께 `WWW-Authenticate: Digest realm=..., nonce=..., qop="auth", algorithm=...`을 돌려줍니다. 클라이언트는 `HA1 = H(username:realm:password)`, `HA2 = H(method:uri)`를 계산하고, `response = H(HA1:nonce:nc:cnonce:qop:HA2)` 형태로 최종 해시를 만들어 Authorization 헤더에 담아 재요청합니다. cnonce(클라이언트 nonce)와 nc(nonce count)는 재전송·리플레이를 막기 위한 장치입니다.

원래 MD5를 쓰도록 설계되어 오늘날 기준으로는 해시 강도가 약하고, `-sess` 변형과 SHA-256 지원이 추가됐지만 브라우저 구현·상호운용성이 들쭉날쭉합니다. 또한 서버가 비밀번호를 검증하려면 HA1(=`H(user:realm:password)`)을 저장해야 하는 경우가 많아, 현대적인 솔티드 해시(bcrypt/argon2) 저장과 어울리지 않습니다.

결정적으로 TLS가 보편화되면서 'HTTPS + Basic' 또는 'HTTPS + Bearer'가 Digest의 장점을 대부분 대체했습니다. 그래서 Digest는 사실상 레거시로 분류되며, 신규 설계에서는 거의 채택하지 않습니다.

요청 / 응답 예시

Authorization: Digest username="alice", realm="api@example.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41"

코드로 보기

# curl performs the challenge/response handshake for you
curl --digest -u alice:s3cret https://api.example.com/protected
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="api@example.com", qop="auth", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41", algorithm=SHA-256

보안 고려사항

관련 헤더

관련 상태코드