MITM과 SSL 인증서

클라이언트를 유저한테 제공했을때 MITM을 견딜 방법이 있을까?

위의 글에서는 CA 루트 인증서 조작을 통해 "Self-signed certification"을 진짜 인증서로 믿게하고 배포하였다. 즉, 프로그램은 조작된 인증서가 진짜 인증서라고 믿었다는 것이다.

이것이 가능한 이유는 SSL이 작동하는 방식에서 찾아볼 수 있다. SSL 헨드쉐이크를 들여다보면

  1. 클라이언트가 서버측에 접속 요청
  2. 서버가 클라이언트에게 자신의 인증서를 전송
  3. 클라이언트는 인증서가 신뢰할만 한 것인지 확인. 문제가 없다고 판단되면 SSL 작업을 이어감

이라는 루틴을 가진다. 여기서 "클라이언트가 서버측에서 제공한 인증서를 어떻게 검증"하는가가 중요한 포인트이다.

클라이언트는 서버측에서 제공한 인증서를 검증하기 위해 미리 자신의 저장공간에 믿을수 있는 인증서(Trutsted root CA Certification) 를 가지고 있다. 서버가 보낸 인증서를 그 자체로는 믿을수 없기에 믿을수 있는 인증서가 사인해 준 흔적이 있으면 믿어주는것이다.

말이 아리송 할 수 있다. 이것을 현실세계로 생각해 보자.

여러분이 A라는 기업과 계약을 하려고 한다. 그런데 A라는 업체에게서 계약서를 송부받았는데, 이 계약서가 누군가에 의해 조작되었을 가능성이 있었다. 그렇기 위해 이 계약서가 유효한지(조작되지 않았는지) 확인할 필요가 생겼다.

여기까지가 MITM의 시도에 대한 이야기이다. 이것을 막기 위해서는 여러 방법이 존재한다

  1. 매번 사원을 보내서 계약서를 받게 한다. ⇒ 프로그래밍의 입장에서 보면 전용선을 설치하는것과 같다. 각 클라이언트에서 부터 서버까지 1:1로 인터넷선을 깔아서 운용하는 방식이다. 클라이언트-서버 사이의 거리가 매우 멀거나(부산, 제주도 to 서울) 클라이언트의 수가 엄청나게 많으면 이 방법은 어렵다. 물론 애초에 가격적으로도 힘들다.
  2. 계약서에 공증을 받는다. ⇒ 이것이 위에서 말한 믿을수 있는 인증서로 한번더 사인을 한다는 개념이다. 계약서 그 자체로는 이것이 조작됐는지 안됐는지 알 수 없다. 그래서 계약서에 A사의 사인과 법원의 공증 서명을 같이 넣는것 이다.

물론, 처음에는 법원의 서명도 맞는지 틀린지 알 수 없다. 그렇기에 미리 법원의 서명을 대조할 수 있도록 "원본 사인"을 가지고 있어야 한다. 이것을 이용해 법원의 원본 사인이 들어가 있는 계약서는 (A사 뿐 아니라 모든 계약서) 모두 "조작되지 않은 인증서"라고 받아주는 것이다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/eb458b75-ef1a-4406-96b4-29e37cd46e89/Untitled.png

위의 스크린샷은 esukmean.com의 인증서 구조를 찍은 것이다. 스크린샷을 보면 Baltimore CyberTrust Root 아래에 Cloudflare Inc ECC CA-3 가 있고, 그 아래에 sni.cloudflaressl.com가 있는것을 볼 수 있다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/46863bd9-21f3-41ed-b8c7-66fff799dc88/Untitled.png