HTTPS란 뭘까? HTTP + Secure, 즉 HTTP에 보안 기능을 추가한 것이다. 기존 HTTP에는 데이터 송수신 과정에서 암호화가 없었기에 개인정보 탈취 위험성이 높았고 이를 방지하기 위해 탄생하였다.
HTTPS를 구현하기 위해서는 3가지가 필요하다.
HTTP 통신 과정
서버측 운영자는 CA로부터 공인 인증서 ( SSL ) 를 발급 받아 서버측에 통신을 요청한 클라이언트에게 공인인증서를 전송하고 자신의 무결성 ( 해커가 아니라는 사실 ) 을 입증한다.
그렇다면 CA로부터 인증서를 발급받기 위해 필요한건 무엇이 있을까? 암호화를 위한 키가 필요하다.
암호화 방식에는 대칭키, 비대칭키( 공개키 ) 방식이 있는데 대칭키는 암호화, 복호화를 위한 키가 동일한 방식이고 후자의 경우는 암호화를 위한 키와 복호화를 위한 키가 다르다. 즉 비대칭키 방식은 2개의 키를 갖는다.
서버는 비대칭키와 대칭키 모두를 활용하여 HTTPS를 구현한다. 초기 검증에는 비대칭키를 사용하고 검증이 완료된 후 본격적인 데이터 통신을 위해 생성하는 세션키에는 대칭키를 사용한다.
비대칭키 방식에서는 비밀키(Private Key)로 암호화하고 공개키(Public Key)로 복호화할 수 있고 반대로 공개키로 암호화 비밀키로 복호화할 수도 있다.
이 두개의 키를 활용하여 서버는 CA로부터 SSL 인증서를 발급 받은 후 이를 이용하여 데이터 통신 전에 클라이언트측에게 자신의 신원을 검증받는다.
클라이언트의 access가 서버에 들어오면 서버는 SSL을 제공하고 클라이언트 ( 브라우저 ) 는 내장되어 있는 CA들 중 해당하는 목록을 찾아 그 CA의 공개키로 복호화하여 서버의 무결성을 증명한다.
( 비대칭키 방식 )
브라우저의 검증 과정에서 올바른 SSL이 아니라면 다음과 같은 오류 화면을 띄운다.
브라우저가 성공적으로 SSL 인증을 마쳤다면 본격적인 데이터 통신을 위한 암호화를 진행한다.
검증이 완료되어 추출된 SSL의 공개키를 이용하여 랜덤값을 암호화하여 전달하면 서버는 이를 비밀키로 복호화하여 세션키를 생성한다. 이후 이 세션키를 클라이언트에게 전달한다.
이제 서버와 클라이언트는 데이터 통신을 할 때마다 이 세션키를 통해 서로를 증명하고 데이터를 주고받는다. ( 대칭키 방식 )
ex ) 클라이언트는 PW/ID를 세션키를 혼합 생성하여 서버에 전달하고 서버는 이를 세션키로 복호화한 후 다시 응답 데이터를 세션키와 혼합하여 전송한다.
HTTPS를 쉽게 말하면 공인된 '인증 기관'에게 내 서버의 '주민등록증'(SSL인증서)을 발급받고, '브라우저'와 통신할 때마다 제시하며 "나 인증받은 서버야." 라고 알리는 방식이다.
- 내 서버의 비밀키/공개키 생성
- '서버 공개키'를 CA 전달하면서 'SSL인증서' 발급 요청
- CA는 'CA비밀키로 암호화된 인증서' 발급
- 클라이언트(브라우저)가 서버에 접속 : Client Hello라고 한다.
○ 클라이언트에서 생성한 '랜덤 데이터' 전송 to 서버
○ 클라이언트가 지원하는 '암호화 방식들' 전송 to 서버
○ 세션 아이디(식별자) 전송 to 서버
- 서버가 클라이언트에 응답: Server Hello라고 한다.
○ 서버에서 생성한 '랜덤 데이터' 전송 to 클라이언트
○ 서버가 선택한 '암호화 방식' 전송 to 클라이언트 (서로 암호화 방식을 맞추는 작업)
○ '인증서' 전송 to 클라이언트
- 클라이언트의 확인 작업
○ 서버에게 받은 인증서 확인: 브라우저에 내장된 CA리스트에 있는 CA의 인증서인지 확인
○ 인증서 복호화: 브라우저에 내장된 해당CA의 공개키로 복호화
○ 복호화 성공시, 인증서가 CA에 의해 발급된 것임이 증명됨
○ 인증서를 전송한 서버도 CA가 보증하는 서버임이 증명됨
○ 복호화된 인증서의 '서버 공개키' 획득
- 클라이언트의 'pre master secret key' 생성
○ pre master secret 키 생성 :
-- '서버에게 받은 랜덤 데이터' + '클라이언트 생성 랜덤 데이터' 조합하여 특정값 생성
○ pre master secret 키 암호화 : 인증서에 있는 '서버 공개키'로 암호화
○ '암호화된 pre master secret 키' 전송 to 서버
- 서버의 'session key'(대칭키의 key) 생성
○ '암호화된 pre master secret 키'를 받아서 '서버 비밀키'로 복호화
○ '복호화된 pre master secret 키'를 이용해 master secret 값 생성하고
○ 최종적으로 session key라는 걸 생성하여 클라이언트와 공유
-- 클라이언트-서버는 데이터를 주고 받을 때, session key를 통해 '대칭키 방식'으로 암호화하여 통신한다.
- 핸드쉐이크 종료
○ 서버의 신원이 확인되었고, 데이터 통신에 사용할 '대칭키 암호화 키값(session key)'도 공유하게 되었다.
- 클라이언트의 데이터 암호화/전송
○ 'session key'를 통해 대칭키 방식으로 데이터(ID/PW 등)를 암호화하여 서버에 전송
- 서버의 데이터 복호화
○ 'session key'를 통해 대칭키 방식으로 데이터를 복호화하여 처리
○ 'session key'를 통해 대칭키 방식으로 응답 데이터 (사용자 정보 등)를 암호화하여 클라이언트에 전송
- 클라이언트의 데이터 복호화
○ 'session key'를 통해 대칭키 방식으로 데이터를 복호화하여 처리
- 데이터 전송 종료
- SSL 통신 종료
- 'session key' 폐기
-- 매번 연결 시마다 새로운 session key를 생성하여 아주 짧은 시간만 사용하므로, 혹시 탈취되더라도 비교적 안전하다.
출처: https://curryyou.tistory.com/207
SSL인증서를 발급하는 공인된 민간기업들.
CA로 유명한 회사로는 Comodo, GoDaddy, Let's Encrypt(무료) 등이 있다.
각 브라우저(크롬, 사파리 등)들은 공인 CA들의 목록을 내부에 저장하고 있다.
방식: 암호화, 복호화에 동일한 key 를 사용
단점: 서버와 브라우저가 동일한 key를 사용하므로, 외부에 노출되면 보안성 저하
2개의 key 생성 ( Private, Public )
서버측 소유 ( 비밀키 : Private Key )
나머지 하나는 브라우저들에게 제공 ( 공개키: Public Key )
< 데이터 통신 활용 >
예) 로그인: 브라우저에서 ID/PW를 공개키로 암호화해서 보내면, 서버는 비밀키로 복호화해서 로그인 처리한다.
< 인증 활용 >
예) 전자서명: 서버가 비밀키로 암호화하여 보낸 데이터를, 브라우저가 공개키로 복호화할 수 있다면 서버의 무결성 입증 가능
< 생성된 공개키의 모습 >