-
Notifications
You must be signed in to change notification settings - Fork 0
Description
지난주, 지지난주 다.. 거의 개요만 썼었는데.. 벌써 끝이라고요...?
평일엔 바빴다지만 게으른 제 탓입니다 ㅠㅠ 제목도 바꿔 놨어요.
오늘은 DB 구현하면서 절 괴롭혔던 TLS를 한 번 정리해보려고 합니다.
보안 중요해요. 근데 보안 구현은 왜 그리 하기 귀찮고 싫은지... 알아서 양심 지켰으면 좋겠지만 세상이 그럴 리 없죠. 그래서 정리해둡니다.
SSL
SSL은 보안 소켓 계층(Secure Sockets Layer, SSL)의 줄임말로, 인터넷에서 데이터를 안전하게 전송하기 위한 암호화 프로토콜이다. 웹 브라우저와 서버간의 통신을 암호화하여 중간에서 데이터가 도청되거나 조작되는 것을 방지하는 것이 주 목적이며, 나중에 전송 계층 보안(Transport Layer Security, TLS)으로 발전하게 된다. 그러나 종종 SSL이 TLS를 포함한 암호화 프로토콜을 지칭할 때 사용되기도 한다.
주요 기능
- 암호화(encryption)
- 서버와 클라이언트 간의 데이터가 제 3자에 의해 탈취되지 않도록 모든 데이터를 암호화한다.
- 인증(authentication)
- 서버가 신뢰할 수 있는지 확인하는 인증서를 사용해 클라이언트와 서버 간의 신뢰 관계를 형성한다.
- 데이터 무결성(integrity)
- 전송되는 데이터가 전송 중 변조되지 않았는지 확인할 수 있도록 무결성을 보장한다.
통신 과정
SSL은 대칭키(공개키) 방식, 비대칭키(비밀키) 방식을 사용하여 보안성을 높인다. 다음은 통신이 이루어지는 단계별 과정이다.
Handshake
SSL 통신은 클라이언트(예: 웹 브라우저)와 서버(예: 웹 사이트)가 연결될 때 먼저 handshake를 거친다.
-
클라이언트 -> 서버: 클라이언트 헬로 (client hello)
- 클라이언트는 SSL/TLS 연결을 시작하기 위해 서버에 연결 요청을 보낸다.
- 해당 요청에는 클라이언트가 지원하는 암호화 알고리즘 목록과 난수(random number)가 포함된다.
-
서버 -> 클라이언트: 서버 헬로 (server hello)
- 서버는 클라이언트의 요청에 응답하면서 다음 데이터를 포함한다.
- 클라이언트로부터 받은 암호화 방식 중, 서버가 사용할 암호화 알고리즘
- 서버의 공개키, 인증서 발급자(ca), 도메인 등의 정보를 포함한 SSL 인증서
- 서버에서 생성한 난수
- 서버는 클라이언트의 요청에 응답하면서 다음 데이터를 포함한다.
-
클라이언트 -> [공인/사설] CA: 인증서 확인 (certificate verification)
- 서버가 보낸 SSL 인증서가 신뢰할 수 있는 기관에 의해 발급된 것인지 확인한다.
- 공인된 CA (브라우저에 저장된 CA 리스트): 제대로 된 인증서라면 공인 CA의 비밀키로 암호화 되었으므로 공개키로 복호화가 가능할 것이다. 따라서, 공개키로 복호화가 가능하다면 서버에게 받은 인증서가 믿을만 하다는 것이 보증된 것이므로 안전하다.
- 사설 CA: 브라우저에 저장된 CA 리스트에 없다. 믿을만 하지 않으므로 https 경고가 뜬다.
- 서버가 보낸 SSL 인증서가 신뢰할 수 있는 기관에 의해 발급된 것인지 확인한다.
- 공인 CA 인증서
- 유료 / 다수의 사람에게 오픈되는 사이트인 경우 사용 / 브라우저에 안전함 표시가 뜸
- 사설 CA 인증서
- 무료 (keytool, openssl 등) / 브라우저에 안전하지 않음 표시가 뜸 / 공인 인증서에 금지된 정보를 포함 가능
- 자체 서명된 인증서
- CA 없이 발급된 인증서 / 인증서 자체가 CA 역할 / 보안은 약하지만 사용이 쉬움
-
클라이언트 -> 서버: 비밀 세션 키 생성 (Session Key Generation)
- 클라이언트는 서버의 공개키로 세션 키를 암호화하여 서버에 보낸다.
- 해당 세션 키는 이후 대칭키 암호화를 통해 데이터를 안전하게 전송하는 데 사용된다.
-
서버: 서버와 클라이언트의 세션 키 공유
- 서버는 자신의 개인키로 클라이언트가 보낸 세션 키를 복호화한다.
- 이제 클라이언트와 서버는 동일한 세션 키를 공유하게 된다.
암호화된 데이터 전송
- Handshake가 완료되면 클라이언트와 서버는 세션 키를 사용하여 데이터를 암호화된 상태로 주고받는다.
- 세션 키는 대칭 암호화 방식으로 사용되며, 동일한 키로 데이터를 암호화하고 복호화한다.
- 대칭 암호화는 비대칭 암호화보다 빠르기 때문에 데이터 전송 중에는 대칭 암호화가 사용된다.
무결성 검사
- SSL은 데이터의 무결성을 확인하기 위해 **메시지 인증 코드(MAC, Message Authentication Code)**를 사용한다. 이를 통해서 데이터가 중간에 변조되었는지 확인할 수 있다.
- MAC은 통신 중 메시지가 변조되지 않았음을 확인하고, 데이터를 보낸 사람이 신뢰할 수 있는지 인증하는 역할을 한다.
- 동작 원리는 다음과 같다(간단히, 미리 정해진 해시 함수로 데이터를 확인한다).
- 입력 데이터: 송신자는 전송할 데이터(메시지)를 준비한다.
- 비밀키: 송신자와 수신자 간에 미리 공유된 비밀키가 있다.
- 해시 함수: 송신자는 데이터와 비밀키를 특정 해시 함수나 암호화 알고리즘에 입력하여 MAC 값을 생성한다.
- 전송: 송신자는 원본 데이터와 함께 생성된 MAC 값을 수신자에게 보낸다.
- 검증: 수신자는 받은 데이터와 비밀키를 사용해 MAC 값을 재계산하고, 송신자가 보낸 MAC 값과 일치하는지 비교한다. 일치하면 데이터가 변조되지 않았음을 확인하고, 그렇지 않다면 데이터가 중간에 변조되었거나, 신뢰할 수 없는 송신자로부터 왔다고 판단한다.
- HMAC, CMAC, PMAC 등의 종류가 있다.
- 만약 데이터가 전송 중 변경되었다면 클라이언트와 서버는 이 사실을 감지하고 연결을 종료할 수 있다.
TLS
TLS 또한 인터넷에서 데이터를 안전하게 전송하기 위한 암호화 프로토콜로, SSL을 기반으로 발전한 형태이다. 보안과 성능을 개선했다고 한다.
주요 기능
- 암호화(encryption)
- 서버와 클라이언트 간의 데이터가 제 3자에 의해 탈취되지 않도록 모든 데이터를 암호화한다.
- 인증(authentication)
- 서버가 신뢰할 수 있는지 확인하는 인증서를 사용해 클라이언트와 서버 간의 신뢰 관계를 형성한다. 경우에 따라서 클라이언트도 인증할 수 있다(mTLS).
- 데이터 무결성(integrity)
- 전송되는 데이터가 전송 중 변조되지 않았는지 확인할 수 있도록 무결성을 보장한다.
통신 과정
SSL은 대칭키(공개키) 방식, 비대칭키(비밀키) 방식을 사용하여 보안성을 높인다. 다음은 통신이 이루어지는 단계별 과정이다.
Handshake
TLS 통신은 클라이언트(예: 웹 브라우저)와 서버(예: 웹 사이트)가 연결될 때 먼저 handshake를 거친다.
-
클라이언트 -> 서버: 클라이언트 헬로 (client hello)
- 클라이언트는 TLS 연결을 시작하기 위해 서버에 연결 요청을 보낸다.
- 해당 요청에는 다음을 포함한다.
- 클라이언트가 지원하는 TLS 버전
- 클라이언트가 사용할 수 있는 암호화 방식(Cipher Suite 목록)
- 클라이언트에서 생성한 난수
-
서버 -> 클라이언트: 서버 헬로 (server hello)
- 서버는 클라이언트의 요청에 응답하면서 다음 데이터를 포함한다.
- 선택한 TLS 버전
- 클라이언트로부터 받은 암호화 방식 중, 서버가 사용할 암호화 알고리즘
- 서버에서 생성한 난수
- 서버의 공개키, 신원을 포함한 디지털 인증서(SSL/TLS 인증서)
- 서버는 클라이언트의 요청에 응답하면서 다음 데이터를 포함한다.
-
클라이언트 -> 서버: 서버 인증 및 키 교환 (Server Authentication and Key Exchange)
- 클라이언트는 서버가 보낸 인증서를 신뢰할 수 있는 **인증 기관(CA)**이 발급했는지 확인하여 서버의 신원을 인증한다.
- 서버 인증 후, 클라이언트는 프리마스터 시크릿(Pre-Master Secret)이라고 불리는 임시 암호화 키를 생성하고, 이 값을 서버의 공개키로 암호화하여 서버로 보낸다.
- 이 과정은 서버의 개인키로만 해독할 수 있다.
-
세션 키 생성 (Session Key Generation)
- 서버는 자신의 개인키를 사용해 클라이언트가 보낸 프리마스터 시크릿을 복호화한다.
- 클라이언트와 서버는 이제 서로가 제공한 난수와 프리마스터 시크릿을 조합하여 세션 키를 생성한다.
- 세션 키는 이후의 데이터 전송에서 대칭키 암호화를 사용해 데이터를 암호화하고 복호화하는 데 사용
-
암호화된 데이터 전송 (Encrypted Data Transmission)
- 세션 키가 설정되면, 이후 모든 통신은 대칭 암호화 방식으로 이루어진다.
- 대칭 암호화는 속도가 빠르고 효율적이기 때문에, 데이터 전송 시 주로 사용된다.
- 양쪽에서 데이터를 전송할 때 무결성 검사를 위한 MAC(Messaging Authentication Code)이 추가되어 데이터가 변조되지 않았는지 확인할 수 있다.
-
핸드셰이크 완료 (Handshake Finished)
- 마지막으로, 클라이언트와 서버는 "Finished" 메시지를 교환하여 핸드셰이크가 완료되었음을 서로에게 알린다. 이 시점부터 클라이언트와 서버는 안전하게 데이터를 암호화하여 주고받을 수 있다.
주요 이점
- 보안성 강화: TLS는 데이터를 암호화하여, 중간에서 공격자가 데이터를 훔치거나 변조하는 것을 방지
- 서버 인증: 디지털 인증서를 통해 서버의 신뢰성을 보장하며, 필요에 따라 클라이언트 인증도 지원
- 호환성: TLS는 다양한 암호화 알고리즘과 인증 방법을 지원하므로 여러 환경에 적용 가능
- 성능 개선: 대칭 암호화를 사용하여 데이터 전송 속도와 효율성을 높이면서도 보안성을 유지
따라서 최근에는 SSL보다 TLS를 대부분 쓰는 것으로 보인다. 본인도 얼마전에 TLS 인증서 받아다가 적용하는데 생각보다 복잡했다.
다들 고생하셨습니다!