컴퓨터는 모니터 앞에 앉아 있는 사람이 누구인지도 알 수 없고, 네트워크 저편에 누가 있는지 알수 없음
-> 만약 클라이언트에게 이름을 알려달라하여 이름을 받았다 하더라도, 이것이 진짜인지 확인할 길이 없음
-> 따라서 등록된 본인만이 알고 있는 정보
나 등록한 본인만이 가지고 있는 정보
등으로 확인할 필요가 있음
이때 상대가 가짜라고 하더라도, 본인 확인을 하기 위한 정보를 제시할 수 있다면, 컴퓨터는 본인으로 인식해 버림
-> 따라서 패스워드 등의 정보는 타인에게 알려지지 않게 하고 쉽게 추측할 수 없도록 해야 함
HTTP/1.1에서 이용할 수 있는 인증 방식
HTTP/1.0에 구현된 인증 방식으로 현재에도 일부 사용됨
-> 웹 서버와 대응하고 있는 클라이언트 사이에서 이뤄지는 인증 방식
1. 리퀘스트 송신
GET /private / HTTP / 1.1
Host:hackr.jp
2. 상태 코드 401로 응답해서 인증이 필요하다는 것을 전달
HTTP/1.1 401 Authorization Required
DAte: Mon, 19 Sep 2011 08:38:32 GMT
Server : Apache/2.2.3(Unix)
WWW-Authenticate Basic realm = "Input Your Id and Password"
3. 유저 ID와 패스워드를 Base64 형식으로 인코드 한것을 송신(클라이언트)
GET /private /HTTP/1.1
Host : hackr.jp
Authorization : Basic Z3vl~~~~~~~
4. 인증이 성공한 경우에는 200 리스폰스, 실패한 경우 401로 다시 응답
2) BASIC 인증이 필요한 리소스에 리퀘스트가 있을 경우, 서버는 상태 코드 401 Authorization Required와 함께 인증의 방식(BASIC)과 Request-URI의 보호 공간을 식별 하기 위한 문자열(realm)을 WWWW-Authenticate 헤더 필드에 포함해서 리스폰스를 반환
3) 유저 ID와 패스워드를 콜론 : 으로 연결한 문장을 Base64라고 불리는 형식으로 인코드 한 것
-> 이를 Authorization 헤더 필드에 포함해서 리퀘스트를 송신
-> 클라이언트에서 브라우저를 사용하는 경우엔 유저 ID와 패스워드 입력시 브라우저가 자동적으로 Base64로 변환
BASIC 인증 에서는 Base64
라는 인코딩 형식 사용
-> 이는 암호화가 아니기에 아무런 부가 정보 없이도 복호화 가능
-> HTTPS가 아닌 암호화 되지 않은 통신 경로 상에서는 복호화된 유저 ID와 패스워드를 뺏길 가능성이 있음
-> 한번 BASIC 인증을 하면, 일반 브라우저에서는 로그아웃할 수 없다는 문제도 존재
BASIC 인증은 많은 웹 사이트에서 요구되는 보안 등급에는 미치지 못한다는 면에서 그다지 사용되지 않음
챌린지 리스폰스 방식
이 사용되고 있어 BASIC 인증과 같이 패스워드를 있는 그대로 보내지 않음
챌린지 리스폰스 방식 : (클라이언트에서) 상대방에게 인증 요구
를 보내고, 상대방 측(서버)에서 (클라이언트에게) 챌린지 코드
를 보내줌
-> 클라이언트가 서버에게서 받은 챌린지 코드를 사용해서 리스폰스 코드
를 계산하고, 이 값을 상대에게 송신하여 인증을 진행하는 방식
리스폰스 코드라는 패스워드
와 챌린지 코드
를 이용해서 계산한 결과를 상대에게 보내기 떄문에, BASIC 인증과 같은 방식에 비하면 PW 누출 가능성이 줄어듬
1. 리퀘스트 송신
GET /digest/HTTP/1.1
Host:hackr.jp
2. 인증이 필요하다는 401 코드와 함께 패스워드와 챌린지 코드(nonce)를 송신
HTTP/1.1 401 Authorization Required
WWW-Authenticate : Digest realm = "DIGEST",
nonce = "MQSQZ0itBAA=44abb6784cc0cbcfc05a", algorithm = MD%, qop="auth"
3. 패스워드와 챌린지 코드에서 리스폰스 코드를 계산해서 송신
GET / digest / HTTP / 1.1
Host: hackr.jp
Authorization:Digest, username = "guest", realm = "DIGEST",
nonce = "MQSQZ0itBAA=44abb6784cc0cbcfc05a", uri="/digest/", algorithm=MD5,
response = "df56389ba3f7c2e8d7551111d67472f", qop = auth,
nc = 000000001, cnonce = "082c875dcb2ca740"
4. 인증이 성공한 경우 200, 실패한 경우 401
HTTP/1.1 200 OK
Authentcation-info:
rspauth= " f218e9ddb4073d", cnonce = "082c875dcb2ca740", nc = 000000001, qop = auth
2) WWW-Authenticate 헤더 필드에 반드시 포함되어야 하는 정보는 realm
, nonce
3) DIGEST 인증을 위해 Authorization 헤더 필드에 반드시 포함되어야 하는 정보는 "username", "realm", "nonce", "uri", "response" 필드
-> 이때 realm과 nonce에는 서버에서 받은것 사용
-> response는 패스워드를 MD5로 계산한 것(리스폰스 코드)
4) 인증 정보가 정확한 겨우, Request-URI의 리소스를 포함한 리스폰스를 반환
DIGEST 인증의 경우 BASIC 인증에 비하면 보안 등급이 높지만, HTTPS의 클라이언트 인증과 비교하면 낮음
-> 웹 사이트에서 요구되는 보안 등급에 미치지 못해 그다지 사용되지 않음
유저 ID와 패스워드를 사용한 인증 방식은 이 두가지 정보가 정확하다면 본인으로서 인증 가능
-> 이 정보가 도난되었을 경우 제 3자가 위장을 하는 경우가 있음
-> 이를 방지하기 위해 SSL 클라이언트 인증이 사용
SSL 클라이언트 인증은 HTTPS의 클라이언트 인증서를 이용한 인증 방식
SSL 클라이언트 인증을 할 때에는 사전에 클라이언트에 클라이언트 증명서를 배포하고 인스톨 해야 함
인증이 필요한 리소스의 리퀘스트가 있는 경우, 서버는 클라이언트에게 클라이언트 증명서를 요구하는 "Certificate Request"
라는 메세지 송신
유저는 송신하는 클라이언트 증명서를 선택후 Client Certificate라는 메세지 송신
서버가 클라이언트 증명서를 검증하여 검증 결과가 정확하다면, 클라이언트의 공개키를 취득. 이후 HTTPS에 의한 암호를 개시함
SSL 클라이언트 인증은 대부분 단독으로 사용되지 않고, 폼 베이스 인증과 합쳐 2-factor 인증의 하나로 사용
-> 인증 요소 한개만이 아닌, 다른 정보를 병용해서 인증을 진행하는 경우
-> ex) SSL 클라이언트 인증을 사용하여 클라이언트의 컴퓨터를 인증하고, 다른 인증 정보로 패스워드를 사용하여 유저의 본인 확인을 진행
폼베이스 인증은 HTTP 프로토콜로서 사양이 정의되어 있는 인증 방식은 아님
-> 클라이언트가 서버 상의 웹 애플리케이션에 자격 정보(Credential)를 송신하여 그 자격 정보의 검증 결과에 따라 인증을 진행하는 방식
-> 웹 애플리케이션에 따라 제공되는 인터페이스나 인증의 방법이 다양
BASIC이나 DIGEST 인증은 보안적인 문제로 거의 사용되지 않고, 보안 등급이 높은 SSL 클라이언트 인증도 도입 비용이나 운용 비용 등의 문제로 널리 사용되지 못함
-> 웹 사이트 인증 기능으로서 요구되는 기능의 레벨을 충족시킨 표준적인 것이 존재하지 않기 때문에 웹 애플리케이션에서 제각각 구현하는 폼베이스 인증을 채용하는 경우가 많음
폼 베이스 인증에서는 기본적으로 세션 관리를 위해 쿠키를 사용
-> 폼 베이스 인증의 인증 자체는 서버 측의 웹 애플리케이션
등에 의해서 클라이언트가 송신해온 유저 ID와 패스워드가 사전에 등록하고 있는 것과 일치하는지 어떤지를 검증하며 이루어짐
-> But HTTP는 Stateless protocol이기 때문에 방금 전에 인증을 성공했던 유저라는 상태를 프로토콜 레벨에서 유지할 수 없음
(즉 다음에 그 유저가 엑세스 했다해도 다른 유저에 구별하지 못함)
-> 따라서 세션 관리
와 쿠키
를 사용하여 HTTP에 없는 상태 관리 기능을 보충
클라이언트와 서버에 유저 ID나 패스워드 등의 자격 정보를 포함한 리퀘스트를 송신(보통 POST 메서드가 사용)
서버 측은 유저를 식별하기 위해서 세션 ID를 발행
클라이언트에서 수신한 자격 정보를 검증하는 것으로 인증을 하고, 그 유저의 인증 상태를 세션 ID와 연관지어 서버측에 기록
이후, 클라이언트 측에 송신할 때 Set-Cookie 헤더 필드
에 세션 ID
를 저장하여 리스폰스 내려 보냄
세션 ID가 탈취되면 주인 행세를 할수 있기 때문에, 어려운 문자열을 사용하거나 서버 측에서 유효기한을 관리하는 등 보안을 유지할 필요가 있음
-> XSS 등의 취약성이 존재할 경우 피해를 줄이기 위해 쿠키에 httponly 속성 부여
폼 베이스 인증에서는 자격 정보를 교환하는 방법이 표준화 되어 있지 않을 뿐 아니라, 패스워드와 같은 Credentials(자격 정보)를 서버 측에 어떻게 보존해야 하는지도 표준화 되어 있지 않음
-> 일반적으로 패스워드를 salt라는 부가 정보를 사용해서 해시라는 알고리즘으로 계산한 값을 저장하지만, 평문을 보존하는 경우도 많은데 이 경우 누설의 위험이 존재