[HTTP 완벽가이드] 13장. 다이제스트 인증

밈무·2023년 2월 17일
0

HTTP완벽가이드

목록 보기
10/14

기본 인증은 편리하고 유연하지만 안전하지 않다. 사용자 이름과 비밀번호를 평문으로 보내고, 메시지를 위조하지 못하게 보호하는 어떤 시도도 하지 않는다. base-64 인코딩을 이용해 뒤섞기만 하여 쉽게 디코딩된다.

다이제스트 인증은 기본 인증과 호환되는 더 안전한 대체재로서 개발되었다. (그렇게 많이 사용되지는 않는다.)

  • 비밀번호를 네트워크를 통해 평문으로 전송하지 않는다.
  • 인증 체결을 가로채서 재현하려는 악의적인 사람들을 차단한다.
  • 구현에 따라 메시지 내용 위조를 막을 수 있다.
  • 몇몇 잘 알려진 형태의 공격을 막는다.

다이제스트 인증은 비밀번호 자체를 보호하는 것이지 그 외의 어떤 비밀 보호를 제공하는 것은 아니기 때문에(즉, 요청&응답 외의 다른 부분에 대해선 다른 사람이 엿볼 수 있다) TLS와 HTTPS보다 안전한 프로토콜이라 볼 수는 없다.

13.1.1 비밀번호를 안전하게 지키기 위해 요약 사용하기

다이제스트 인증에서 가장 중요한 것은 비밀번호를 네트워크를 통해 보내지 않는 것이다. 비밀번호를 보내는 대신에 클라이언트는 비밀번호를 비가역적으로 뒤섞은 fingerprint(지문) 또는 digest(요약)을 보낸다.
서버와 클라이언트가 모두 비밀번호를 알고 있기 때문에 서버가 클라이언트가 보낸 요약과 자신이 계산한 요약이 일치하는지 확인하는 방식으로 인증이 동작한다.

13.1.2 단방향 요약

요약은 단방향 함수로 동작하고, 일반적으로 입력 가능한 무한 가지의 모든 입력값들을 유한한 범위의 압축으로 변환한다.(충돌(=다른 입력값에 같은 요약)이 발생할 수는 있지만 확률이 무시해도 될 만큼 작고, 비밀번호를 맞춰본다는 목적을 생각해볼때 중요하지 않다)
MD5SHA가 인기 있는 요약 함수 중 하나이다.

요약함수는 보통 암호 체크섬이라고 불리고, 단방향 해시 함수이거나 지문 함수(fingerprint function)이다.

13.1.3 재전송 방지를 위한 nonce 사용

요약을 가로채서 서버로 재전송하는 재전송 공격을 방지하기 위해 서버가 클라이언트에게 난스를 건네준다.
난스를 비밀번호에 섞어서 난스가 바뀔 때마다 요약도 바뀌게 만들어준다.

13.1.4 다이제스트 인증 핸드셰이크

  1. 서버가 난스를 생성한다.
  2. 서버가 영역(realm), 난스, 알고리즘을 보낸다. (인증 요구)
  3. 알고리즘을 선택하고 응답 요약을 생성한다.
  4. 클라이언트가 요약을 담아서 서버에게 돌려준다. 만약 클라이언트가 서버 인증을 원한다면 클라이언트 난스를 생성하여 함께 보낼 수도 있다.
  5. 서버는 클라이언트가 했던 그대로 요약을 계산한 다음 자신이 계산한 요약과 네트워크로 전송되어 온 요약이 일치하는지 확인한다. 만약에 클라이언트가 대칭적으로 서버에게 클라이언트 난스를 가지고 인증을 요구했다면, 클라이언트 요약이 만들어진다.

13.2 요약 계산

13.2.1 요약 알고리즘 입력 데이터

요약은 다음의 세 요소로부터 계산된다.
1. 단방향 해시 함수 H(d) & 요약 함수 KD(s,d) (s는 비밀, d는 데이터)
2. 비밀번호 등 보안 정보를 담고 있는 데이터 덩어리. A1
3. 요청 메시지의 비밀이 아닌 속성을 담고 있는 데이터 덩어리. A2

13.2.3 보안 관련 데이터(A1)

A1은 사용자 이름, 비밀번호, 보호 영역, 난스와 같은 비밀 보호 정보로 이루어진 데이터 덩어리이다. (비밀 정보와만 관련)

MD5

모든 요청마다 단방향 해시를 실행하는 알고리즘

A1 = <사용자>:<영역>:<비번>

MD5-sess

사용자 이름, 영역, 비밀번호에 대한 해시를 계산한 결과 뒤에 현재 난스와 클라이언트 난스를 붙인 것이 A1.

A1 = MD5(<사용자>:<영역>:<비밀번호>):<난스>:<c난스>

13.2.4 메시지 관련 데이터(A2)

A2는 URL, 요청 메서드, 메시지 엔터티 본문과 같은 메시지 자체의 정보를 나타낸다. 메서드, 리소스, 메시지의 위조를 방지하기 위해 사용된다.

13.2.5 요약 알고리즘 전반

H, KD, A1, A2를 사용해서 다이제스트를 산출한다.

13.2.6 다이제스트 인증 세션

WWW-Authenticate 인증 요구에 대한 클라이언트의 응답으로 그 보호 공간에 대한 인증 세션을 시작하게 한다.
인증 세션은 클라이언트가 다른 서버로부터 또다른 WWW-Authenticate 인증 요구를 받을 때까지 계속된다. 클라이언트는 인증과 관련된 정보(사용자 이름, 비번, 난스, 난스 횟수, 미래 요청에 들어갈 Authorization 헤더를 만들기 위한 인증세션과 관련된 값)를 기억하고 있어야 한다.

  • 난스가 만료되면?
    • 서버는 포함된 난스값이 낡은 것일 수 있음을 감수하고 오래된 Authorization헤더 정보를 받아들일 수 있다.
    • 서버는 클라이언트가 다시 요청을 보내도록 새 난스 값과 함께 401 응답을 반환할 수 있다. -> 클라이언트가 새 난스 값으로 다시 요청 보냄

13.2.7 사전(preemptive) 인가

  • 일반적인 인증에서는 트랜잭션이 완료 되기 전에 요청/인증 요구 사이클을 필요로 한다.
  • 만약 클라이언트가 다음 난스가 무엇인지 알고 있어서 서버가 인증을 요청하기 전에 올바른 Authorization 헤더를 생성할 수 있다면, 이 요청/인증요구 사이클은 생략될 수 있어 성능 상 개선 효과가 있다.
    => 사전인가 : 메시지 횟수를 줄인다.
  • 사전인가
    • 기본 인증에서 : 브라우저가 사용자의 이름과 비번에 대해 클라이언트 측 데이터베이스를 관리해서 사용자가 어떤 사이트에 한번 인증하면 그 사이트 URL에 대한 다음번 요청에는 올바른 Authorization 헤더를 전송할 수 있다. (12장) -> 간단!
    • 다이제스트 인증에서 : 난스기술이 재전송 공격을 저지하기 위한 것이기 때문에 서버가 임의의 난스를 생성하여 인증요구를 받지 않으면 클라이언트는 올바른 Authorization 헤더를 알 수 없다.
  • 클라이언트가 새 WWW-Authentication 인증 요구를 기다리지 않고 올바른 난스를 취득할 수 있는 방법
    • 다음 난스 미리 생성하기
      Authentication-Info 성공 헤더에 다음 난스 값을 실어서 보낸다.
      • 장점 : 사전 인가를 통해 요청/인증요구 사이클을 생략함으로써 트랜잭션 속도 향상
      • 단점 : 파이프라이닝이 쓸모 없어져(다음 요청 보내기 전에 반드시 다음 난스 값을 받아야 하므로 응답 올 때까지 기다려) 오히려 회전 지연으로 인한 성능상 불이익
    • 제한된 난스 재사용
      "난스를 10초동안 or 5번 재사용 허용" 이런 식으로 난스를 제한적으로 재사용한다.
      • 장점 : 클라이언트가 난스를 미리 알 수 있고, 응답과 관련 없어지므로 파이프라이닝을 할 수 있다.
      • 단점 : 재전송 공격 가능성이 올라가서 보안성이 감소된다.
    • 동기화된 난스 생성
      클라이언트랑 서버가 순차적으로 같은 난스를 생성할 수 있도록 시간적으로 동기화된 난스 생성 알고리즘을 사용한다.

13.2.8 난스 선택

난스 내용은 구현의존적이다.
예를 들어 타임스탬프(반복 불가능한 값)와 ETag(요청된 엔터티에 대한 ETag 헤더값으로, ETag를 포함하면 갱신된 리소스에 대한 재요청을 방지)를 사용하는 방식으로 구현할 수 있다.

13.2.9 상호인증

클라이언트가 서버를 인증할 수 있도록 다이제스트 인증을 확장.
선택사항이지만 보안이 상당히 개선되므로 현대적인 클라이언트와 웹 서버라면 구현하는 게 권장된다.

13.3 보호 수준(Quality of Protection) 향상

qop 필드는 클라이언트와 서버가 어떤 보호 기법을 어느 정도 수준으로 사용할 것인지 협상하게 해준다.
선택적이긴 하지만, 오래된 RFC 2069 명세와의 호환성을 유지하기 위한 것이고, 모든 현대적인 요약 구현은 qop 옵션을 지원해야 한다.

  • auth : 인증
  • auth-int : 인증 및 메시지 무결성 보호

13.3.1 메시지 무결성 보호

qop = "auth-int"
엔터티 본문의 해시에 대해 계산

13.3.2 다이제스트 인증 헤더

13.4 실제 상황에 대한 고려

다이제스트 인증작업을 할 때 고려해야할 것들

13.4.1 다중 인증요구

서버는 한 리소스에 대해 여러 인증을 요구할 수 있다.

13.4.2 오류처리

인증이 적절하지 않았을 때는 400 Bad Request를 반환하고 로그로 기록(공격자일 수도 있음)하는 것이 좋다.

13.4.3 보호 공간

  • 기본인증에서, 클라이언트는 요청 URI와 그 하위 모든 경로가 같은 보호 공간에 있는 것으로 가정한다. -> 또다른 인증 오구를 기다리지 않고 미리 리소스에 대한 인가 받을 수 있다.
  • 다이제스트인증에서, WWW-Authenticate: domain 필드로 보호 공간을 보다 엄밀하게 정의한다.

13.4.4 URL 다시쓰기

프락시가 리소스 변경없이 URI를 다시 쓰기도 하는데, 이와 동시에 다이제스트 인증은 URI값의 무결성을 검사하므로, 이런 변경에 의해 다이제스트 인증이 실패할 수 있다.

13.4.5 캐시

어떤 공유 캐시가 Authotization 헤더를 포함한 요청과 그에 대해 응답을 받은 경우, 두 Cache-Control 지시자 중 하나가 응답에 존재하지 않는 다른 요청에 대해 그 응답을 반환해서는 안된다.

13.5 보안에 대한 고려사항

13.5.1 헤더 부당 변경

양종단 암호화나 헤더에 대한 디지털 서명으로 방지 (두개를 조합할 수 도 있다)

13.5.2 재전송공격

재전송 공격은 누군가가 트랜잭션에서 엿들은 인증 자격을 다른 트랜잭션에서 사용하는 것이다. (난스값 반복 사용으로 발생)
이를 완화하기 위해 클라이언트의 IP 주소, 타임스탬프, ETag, 개인서버키에 대한 요약을 포함하는 난스를 서버가 생성하게 할 수 있지만 클라이언트 ip를 난스생성에 사용하게 되면 프락시팜을 사용할 수 없고, ip주소를 속이는 문제가 발생할 수 있다.
완전히 재전송 공격을 피하기 위해서는 트랜잭션마다 유일한 난스값을 사용하는 것이다.

13.5.3 다중 인증 메커니즘

  • 클라이언트가 언제나 가능한 한 가장 강력한 인증제도를 선택하도록 한다.
  • 위의 방법이 현실적으로 불가능하다면 가장 강력한 인증 제도만을 유지하는 프락시 서버를 사용하자. (사내 네트워크같이 모든 클라이언트가 우리가 선택한 강력한 인증제도를 지원할 수 있다고 알려진 경우에만 사용)

13.5.4 사전 공격

사전(dictionary) 공격은 전형적인 비밀번호 추측공격.
이를 막기 위해 크래킹이 어려운 복잡한 비밀 번호를 사용하거나 비밀번호 만료 정책을 사용할 수 있다.

13.5.5. 악의적인 프락시와 중간자 공격

프락시가 악의적이거나 보안이 허술하다면 클라이언트는 중간자 공격에 취약해질 수 있다. ( 엿듣기 공격이나 가장 약한 인증 제도로 대체)
SSL을 사용해서 공격을 방어하자

13.5.6 선택평문 공격

클라이언트가 서버에서 제공된 난스 대신 선택적인 c난스 지시자를 사용하여 응답을 생성할 수 있도록 한다.

13.5.7 비밀번호 저장

  • 비밀번호 파일 보호 철저히
  • 영역이름이 유일함 보장, 비밀번호 파일이 유출되어도 피해를 특정 영역으로 최소화 (호스트, 도메인을 포함한 완전한 영역이름)
  • SSL

0개의 댓글