-
[Network] HTTPS공부/컴퓨터 네트워크 2024. 5. 21. 15:47반응형
1. HTTP와 HTTPS
HTTP와 HTTPS의 큰 차이점은 패킷이 암호화되냐, 암호화되지 않냐의 차이이다.
HTTP는 80번 포트번호로 패킷을 주고 받고, HTTPS는 443 포트번호로 모든 통신을 진행하게 된다.
아래 와이어샤크를 통해 패킷을 확인해보자
HTTP 패킷
HTTPS 패킷
큰 흐름의 HTTP/HTTPS 트랜잭션
HTTP는 80번 포트를 통해 3-way handshake를 통해 연결을 수립하고, 통신을 하다가 서로 주고 받을 패킷이 없으면 4-way handshake를 통해 통신을 종료한다.
HTTPS는 살짝 다르게 3-way handshake를 한 이후 SSL handshake를 진행하고, 이후 통신을 끊을 때에는 SSL 닫힘 통지가 먼저 일어나는데, 이때 클라이언트와 서버가 close_notify로 서로 통지를 한 이후에야 4-way handshake를 진행하게 된다.
2. SSL / TLS 역사
SSL은 3.0까지 나와있는데 처음엔 게임 버전 같은걸로 생각해서 엄청난 역사가 있을 것 같았지만 찾아보니 근본이 없었다.
SSL 역사 (Secure Sockets Layer)
- 1994년: Netscape 회사에서 웹 브라우저 보안 프로토콜인 SSL 1.0을 제작함 (하지만 너무 이론 중심이라 출시 X)
- 1995년: SSL 2.0을 만들었으나 보안 문제가 발견되어 SSL 3.0 개발 착수
- 1996년: SSL 3.0을 출시하고 많은 사람들이 사용함. 하지만 2015년에 패킷의 일부분을 볼 수 있는 보안 문제가 발견되어 TLS로 넘어감
TLS 역사 (Transport Layer Security)
- 1999년: IETF 기관에서 SSL 3.0보다 보안, 안정성면에서 좋은 TLS 1.0을 제작
- 2000년 이후: TLS 1.1 (2006), TLS 1.2 (2008), TLS 1.3 (2018)로 계속해서 업데이트를 진행중
통계 자료 (2018년 상반기 기준 - 출처)
- 상위 100,000개 사이트에서 79%가 HTTPS 통신을 사용
- 상위 100,000개 사이트중에 6.8%가 SSL 2.0 / 3.0을 지원중 (반대로 말하면 93.2%가 TLS를 사용하고 있음)
생각보다 HTTPS 역사는 짧았지만, 생각보다 많은 사이트에서 HTTPS, TLS를 사용한다는 것을 알 수 있다.
3. 대칭키, 비대칭키
SSL handshake를 보기 전에 우선 대칭키와 비대칭키 개념에 대해 잠깐 짚어보고 넘어가는게 좋다.
[1] 대칭키
- 암호화와 복호화를 하나의 키로 사용하게 된다.
- 예시 알고리즘
- AES 알고리즘 (현재 가장 많이 사용하는 대칭키 알고리즘)
- DES 알고리즘 (AES 이전에 사용하던 표준 암호 알고리즘)
[2] 비대칭키
- 암호화와 복호화에 서로 다른 키를 사용한다.
- 비대칭키를 생성하면 (공개키, 비밀키) 쌍을 생성해준다. 이때 비밀키는 개인/단체가 소유해서 안전하게 관리한다.
- 공개키, 비밀키의 암호화/복호화 예시
- 공개키로 암호화를 하면 비밀키로만 복호화가 가능하므로 데이터 보안에 유리하다.
- 비공개키로 암호화를 하면 공개키로만 복호화가 가능한데, 공개키는 모두에게 공개되어 있으므로 SSL/TLS 인증에 유리하다.
- 예시 알고리즘
- RSA
SSL/TLS에서는 대칭키와 비대칭키 모두 사용한다. 서명 인증 과정은 비대칭키가 중점적으로 사용되고, 이후 통신에서는 대칭키를 통해 서로 패킷을 주고받는다.
4. SSL / TLS Handshake 과정
[4-1] 구체적인 SSL / TLS handshake 동작 과정
이 자료는 살짝 잘못된 내용이 있어서 아래 부분을 유의하고 읽으면 좋다.
- 그림에 나온 CA는 이미 생성된 공개키와 비밀키를 가지고 있다.
- 애초에 CA_Public이 내 컴퓨터에 있다. 그래서 HTTPS 과정 중간에 CA랑 통신을 진행하지 않는다.
위 내용은 macos 기준으로 키체인 목록에서 검색창에 'digicert'를 살펴보면 된다. 이미 공개키가 저장되어 있다.
[인증서 등록]
- [서버] 서버에서 비대칭키를 생성 (Server_Public - 공개키, Server_Private - 비밀키)
- [서버 → 인증서 기관] 사이트 정보와 Server_Public를 통해 SSL 인증서 생성 요청
- [인증서 기관 → 서버] 받은 내용을 CA_Private로 암호화 후, SSL 인증서를 서버에게 전달
[클라이언트에서 서버로 요청을 보내기 시작할 때]
- [클라이언트 → 서버] 클라이언트가 서버에게 인증서를 요구
- [서버 → 클라이언트] 인증서를 전달
- [클라이언트] 컴퓨터에 CA_Public를 통해 인증서를 복호화하고 서명을 검증해서 유효한 서명인지 확인함
- [클라이언트] 클라이언트에서 대칭키를 생성 후, 해당 대칭키를 Server_Public으로 암호화함
- [클라이언트 → 서버] 암호화된 대칭키를 서버로 전달
- [서버] 암호화된 대칭키를 Server_Private으로 복호화를 진행해서 대칭키를 얻음
- [클라이언트 <-> 서버] 이후 대칭키로 암호화해서 진행함
* 클라이언트 - 서버 사이에 CA라는 신뢰 가능한 제3자를 두어서 CA_Public이 없으면 인증서 서명 검증을 할 수 없도록 했다.
[서명 검증 과정]
- [복호화된 해시값] CA_Public으로 인증서를 복호화하면 서명에 사용된 해시 함수와 특정 해시값이 나옴
- [새로운 해시값] 서명에 사용된 해시 함수를 인증서 내용에 해싱하면 새로운 해시값이 나옴
- [복호화된 해시값] = [새로운 해시값] 을 확인해서 같은 값이면 유효한 서명임
[4-2] 실제로 동작하는 SSL/TLS handshake 동작 과정
클라이언트 → 서버는 빨간색, 서버 → 클라이언트는 파란색으로 표시했다.
1. Client Hello: 사용하는 SSL/TLS 버전, 사용 가능한 암호화 알고리즘 목록
2. Server Hello: Client Hello에서 보낸 암호화 알고리즘 선택
- TLS: TLS 통신 진행함
- ECDHE: ECDHE 암호화 알고리즘을 통해 키 교환을 진행함 (비대칭키)
- RSA: 서버의 인증서가 RSA로 암호화 되어 있음 (비대칭키)
- AES_256_GCM: AES 알고리즘을 진행, key size는 256비트이고, GCM 모드로 수행함 (대칭키)
- SHA384: 메시지 인증 코드로 패킷의 손상/변형 여부를 검증함 (해시 함수)
3. Certificate: 서버가 클라이언트에게 인증서 정보를 전송함 (RSA로 암호화되어 있음)
4. Server Hello Done: 서버가 보낼 패킷이 끝났음을 알림
5. Client Key Exchange: 대칭키를 생성하여 Server_Public으로 암호화해서 전송
6. Change Cipher Spec: 협상된 알고리즘과 키로 메시지를 암호화할 것을 알림
7. Finish: 클라이언트에서 보낼 패킷 끝 (패킷을 암호화해서 전송)
8. Change Cipher Spec: 서버도 협상된 알고리즘과 키로 메시지를 암호화할 것을 알림
9. Finish: 서버에서 보낼 패킷 끝 (패킷을 암호화해서 전송)
5. 왜 비대칭키로 통신하지 않고, 대칭키로 통신을 할까?
RSA로 암호화를 한다면 현대 기술로는 거의 뚫을 수 없다는 특징을 가지고 있는데, 왜 비대칭키가 아닌 대칭키로 통신을 하는지 궁금했다. 이론을 봐도 무슨 소리인지 잘 몰라서 실제로는 얼마나 시간 차이가 나길래 그런건지 확인해보았다.
pip install pycryptodome
먼저 pycryptodome을 설치해주자
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP, AES from Crypto.Random import get_random_bytes import time # 데이터 data = b"Hello, World!" * 15 # RSA 키 쌍 생성 rsa_key = RSA.generate(2048) public_key = rsa_key.publickey() cipher_rsa = PKCS1_OAEP.new(public_key) # AES 키 및 초기화 벡터 생성 aes_key = get_random_bytes(32) # 256-bit AES 키 iv = get_random_bytes(16) cipher_aes = AES.new(aes_key, AES.MODE_CFB, iv=iv) # RSA 암호화 start_time = time.time() encrypted_data_rsa = cipher_rsa.encrypt(data) rsa_time = time.time() - start_time # AES 암호화 start_time = time.time() encrypted_data_aes = cipher_aes.encrypt(data) aes_time = time.time() - start_time print(f"RSA 암호화 시간: {rsa_time:.6f} 초") print(f"AES 암호화 시간: {aes_time:.6f} 초")
이후 위 코드를 실행하면 시간이 꽤 많이 차이난다.
"Hello, World!" * 15인 평문만 보내도 20배나 차이나는데, 이게 195 바이트이다. 근데 실제 네트워크 패킷은 MTU가 1500 바이트가 표준 값이니 패킷 보내는 시간까지 포함하면 오랜 시간이 걸릴 것 같다.
6. 궁금해서 찾아본 내용
[6-1] 대칭키 알고리즘 동작 과정
AES 알고리즘은 미국 표준 기술 연구소에서 공모전을 열어 채택한 알고리즘을 AES 알고리즘으로 부르는 것이다. 그래서 실제로는 Rijndael 알고리즘 (레인달 알고리즘)을 사용한다. 주의할 점은 AES-256이면 key size가 256비트 (32바이트)이고, 블록은 128비트 (16바이트)를 사용한다는 것이다.
자세한 동작 과정은 Advanced Encryption Standard 암호화 포스팅 글을 보면 좋다. 16바이트이므로 4x4 행렬을 변환하고, 많은 연산을 수행한다. 참고로 저 블로그에 복호화 글도 있다.
[6-2] SSL / TLS handshake에서 CA_Public은 모두에게 공개된 키일까?
사실 우리 컴퓨터에 저장되어 있다. macos 기준 키체인 접근에 들어가서 검색창에 "DigiCert Global Root CA"를 검색하면 볼 수 있다. 해당 인증서는 운영체제가 설치되거나 업데이트할 때, 같이 생성되거나 업데이트 된다고 한다. 따라서 SSL/TLS handshake은 CA 없이 클라이언트와 서버에서만 서로 통신하는 과정만 존재한다. 사진은 내 노트북을 포맷하긴 좀 그래서 가상 환경에 우분투를 설치해서 확인한 스크린샷이다.
[6-3] 네이버는 TLS v1.3를 사용할까??
아래 과정을 통해 확인할 수 있다
- [설치] brew install openssl
- [터미널에 입력] openssl s_client -connect www.naver.com:443
최신 버전인 TLSv1.3을 사용하는 것을 알 수 있다.
위 사진은 80번 포트인데, 아시다시피 80번 포트는 HTTP라 보안을 지원해주지 않는다는걸 확인할 수 있다.
7. 출처
- CLOUDFLARE - TLS 핸드셰이크의 원리는 무엇일까요?
- 깃허브 - HTTP 완벽 가이드를 정리해둔 레포지토리
- 블로그 - HTTPS 동작 과정 이해해보기
- 블로그 - AES 암호화
- ChatGPT - 4o
반응형'공부 > 컴퓨터 네트워크' 카테고리의 다른 글
[Network] WebSocket (2) 2024.06.14 [컴퓨터 네트워크] 목차 (0) 2022.06.15 12. 웹 페이지 요청에 대한 처리 (0) 2022.06.15 11. 스위치 근거리 네트워크 (0) 2022.06.07 10. 링크 계층 (0) 2022.06.06