연습
CA, SSL-Cert, SSL Commnunication
onaeonae1
2024. 5. 14. 23:28
CA, SSL-Cert, SSL Commnunication
CA, SSL 인증서, SSL 통신 과정에 대해서 간단하게 정리
1. SSL 인증서의 핵심 역할
→ 클라이언트가 접속한 서버가 신뢰할 수 있는 서버(웹 서비스)임을 보장
→ SSL 통신에 사용할 공개키를 클라이언트에게 제공
2. CA(Certificate Authority)
- 인증서의 역할 중, 클라이언트가 접속한 서버가 클라이언트가 의도한 서버임을 보장하는 것 존재
- 의도한 서버가 맞다라고 어떠한 Certificate 를 할 수 있는 Authority 가 필요하다는 것
- 이 역할을 하는 민간기업들이 존재. 이들을 CA(Certificate Authority) 라고 함
- CA는 어떤 기업이나 할 수 있는게 아니라, 까다로운 조건이 필요하다. 엄격한 신뢰성 필요
- SSL 통신을 제공하려는 웹서비스는 CA를 통해 발급 요청 (=구매)
- 인증서를 바로 구매할 수 있는 것은 아니고 CA에서 다양한 방법으로 평가 후 발급해줌
- 서비스 도메인, 공개 키 등에 대한 정보 전달 필요
3. SSL 인증서의 내용
- SSL 인증서에는 다음과 같은 내용이 포함되어 있음
- 웹서비스의 정보 (인증서를 발급한 CA, 서비스의 도메인 등)
- → "웹서비스의 정보" 를 통해 클라이언트는 접속한 서버가 의도한 곳이 맞는지 검증 가능
- 웹서비스 서버 측의 공개키 (공개키의 내용, 공개키의 암호화 방법 등)
- → "서버 측의 공개키" 를 통해 클라이언트는 암호화 통신에 필요한 기본 정보 파악 가능
- SSL 인증서의 내용은 CA에 의해 암호화. 이 때 사용하는 암호화 기법은 공개키 방식→ 이 때 CA 비공개키는 외부에 절대 노출되서는 안됨. 노출되면 CA는 망했다고 보면 됨
- → CA는 자신의 CA 비공개키를 이용해서 서버가 제출한 인증서를 암호화
- SSL 인증서와 CA 정보는 https 통신을 사용하는 웹 서비스에 클라이언트가 접속할 시 전달됨
4. 클라이언트에서 암호화된 인증서 확인 및 서비스 신뢰
4-1. 기본 개념
- 아까 CA는 공인된 민간기업들이라는 사실을 확인함
- 그리고 SSL 인증서는 CA별 비공개키에 의해 암호화된 것
- 따라서, CA별 공개키를 알고 있으면 decode가 가능하다!
- 이렇게 전달받은 인증서를 CA별 공개키로 decode 성공 및 인증서의 유효성 확인 시도
- 이를 모두 성공했다면 다음과 같은 결론을 내릴 수 있다.→ 해당 SSL 인증서는 CA가 발급한게 확실하다→ 해당 웹 서비스는 신뢰할 수 있는 곳이다
- → 접속하려는 웹 서비스는 CA에 의해 검토 후 발급되었음이 확실함
- → 해당 SSL 인증서가 CA 비공개키로 암호화 되었다.
- 이를 통해 SSL 인증서의 첫 번째 목적인 "신뢰할 수 있는 서버임을 보장" 이 만족
4-2. SSL 인증서 decode 및 인증서의 확인 과정
- 클라이언트(=웹 브라우저) 는 내부적으로 CA의 리스트와 각 CA별 공개키 리스트를 가지고 있음
- 웹서비스로부터 전달받은 SSL 인증서와 CA 정보를 바탕으로 인증서의 유효성 검증 진행
- 전달받은 CA 정보가 가지고 있는 CA 리스트에 포함되는가
- CA 리스트에 포함되면 그에 해당하는 공개키로 SSL 인증서를 decode
- 실제 접속중인 내용과 SSL 인증서의 내용을 비교. 특히 웹서비스의 정보를 많이 검증
- 이에 해당하지 않을 경우 브라우저는 경고를 내보낸다.→ CA는 유효하나 인증서의 값이 유효하지 않을 시 강한 경고 출력됨
- → CA 자체가 유효하지 않은 경우 URL 창에 경고 출력됨
4-3. github를 대상으로 인증서 에러 확인
- SSL 인증서의 서비스 정보에는 서비스 도메인이 나와있다.
- 따라서, 서비스 도메인이 올바르지 않게 github에 접속하면 경고창을 확인할 수 있을 것
- 이에 대해 서비스 도메인으로 접근, raw ip 로 접근해서 경고를 확인해보자
python socket 모듈로 github.com 의 ip를 확인해본 결과 15.164.81.167 이다. 이거로 접근해보자
5. SSL 통신 방법
- 인증서에는 서비스 정보, 서버 공개키 정보가 포함됨.
- 서비스 정보는 4에서 정리한 대로 서비스 신뢰 여부 파악에 사용했음
- 서버 공개키 정보는 대체 어디에 쓰는지 의문
5-1. 기본 개념
- 결론부터 말하자면 SSL은 암호화 통신을 위해 대칭키, 공개키를 혼합해 사용한다
- 클라리언트-서버가 주고 받는 실제 request, response data는 대칭키 방식으로 암호화
- 이때 사용하는 대칭키를 공개키 방식으로 암호화
- 공개키로 SSL 통신을 전부 다 처리하는 것은 이상적이나 어제 정리한 대로 너무 자원소모가 큼
- 대칭키는 암호화 통신에 사용하기에는 약간 불안하나 자원소모가 덜하다
- 따라서 SSL은 둘을 혼합해서 사용한다
SSL 통신 방법에 대해 세부적으로 파악하려면 우선 handshake, 세션, 세션 종료로 이어지는 네트워크 통신 파악 필요
5-2. (1) handshake
- handshake 는 Client - Server 간 데이터를 주고 받기 전에 통신을 수립하는 과정
- handshake 과정에서 SSL 인증서를 주고 받고, 서로 간에 사용할 대칭키를 공유
- 이때 대칭키를 외부에 노출되지 않고 서로만 공유하는 데 서버 공개키가 사용됨
- 이 세부적인 과정은 다음과 같다.
- 클라이언트에서 서버에 접속(Client-Hello) 및 다음과 같은 정보 교환
- 클라이언트에서 생성한 랜덤 데이터
- → 데이터 암호화에 사용할 대칭키를 만들기 위한 것. 후술
- 클라이언트가 지원하는 암호화 방식들
- → 브라우저가 가능한 암호화 방식들
- Session ID
- → 이미 통신이 수립되었다면 재활용하기 위해 이를 사용, 초기 연결시엔 없음
- 서버에서 클라이언트로 응답(Server-Hello) 및 다음과 같은 정보 교환
- 서버 측에서 생성한 랜덤 데이터
- → 데이터 암호화에 사용할 대칭키를 만들기 위한 것. 후술
- 서버가 선택한 클라이언트의 암호화 방식→ 둘 모두가 가능한 암호화 방식을 채택하고 이걸 기반으로 암호화 통신 수립
- → 서버가 가지고 있는 암호화 방식과 클라이언트가 가지고 있는 암호화 방식 중 교집합 선택
- SSL 인증서
- 클라이언트의 CA 리스트 확인 및 인증서 유효성 확인(4에서 언급한 내용)
- SSL 인증서를 확인하면서 신뢰할 수 있음을 판단
- 그리고 서버 공개키 정보를 활용해 이후 과정 실행
- client 측에서 pre-matser secret 생성 및 암호화
- 아까 client-hello, server-hello 에서 주고받은 랜덤 데이터를 사용
- 클라이언트, 서버 측에서 생성한 랜덤 데이터 조합 → pre-master-key 생성
- 이는 이후 세션 단계에서 데이터 주고받을 때 암호화에 사용할 것
- 이때 사용하는 암호화 방법은 대칭키므로 외부에 노출이 되면 안됨
- 그럼 서버에 어떻게 전달하는가? 바로 공개키 방식을 사용한다
- 서버의 공개키(SSL 인증서에 있는것)로 pre-master-key를 암호화해 서버로 전송
- 그러면 서버에서 자신의 서버 비공개키로 decode가 가능!
- server 측에서 pre-master-secret decode, session-key 생성
- 클라이언트에서 생성한 pre-master-secret 을 사용해서 decode
- decode 완료하면 이를 master-secret 이라고 함
- 그리고 이 master-secret 으로 session-key 라는 것을 만듬
- 이 session-key 로 클라이언트와 서버는 데이터를 대칭키 방식으로 암호화
- session-key가 외부에 노출되지 않고 서로 공유할 수 있게 됨
- 클라이언트에서 서버에 접속(Client-Hello) 및 다음과 같은 정보 교환
5-3. (2) 세션
- 세션에서 클라이언트와 서버는 실제 데이터를 주고 받음
- handshake 를 통해 얻은 session-key를 기반으로 대칭키 암호화
- handshake를 처음 수행할 때 공개키 암호화를 하므로 컴퓨터 자원 소모 큼
- 그래서 세션이 종료되지 않고 유지된 경우에는 그대로 재사용하는 것
5-4. (3) 세션 종료
- 통신이 종료되면 SSL 통신이 종료되었음을 서로에게 알림
- 사용한 session-key 를 폐기