인증서는 어떻게 동작하는 것일까?

개발자분들과 자유주제로 발표하는 스터디에 참여하고 있다. 요새 업무도 AWS에 kubernetes를 올려서 ingress로 ambassador를 사용하는데 https에 대한 처리를 어떻게 해야하나😯를 주제로 회의를 했었는데 (정확히는 수석님이 search한 내용을 들은 것이지만) 스터디에서도 인증서 관련 내용을 들어서 도움이 많이 됐다.


## 암호화 방식 #### 대칭키 대칭키는 말 그대로 `heeye`라는 키로 암호화를 하면, 복호화할 때 `heeye`라는 키를 사용하는 방식이다.

공개키, 개인키

대칭키를 사용했을 때 단점이 heeye라는 키를 누군가 알기라도 하면, 암호화된 데이터를 복호화할 수 있다. 보안에 취약하다! 이 단점을 보완하기 위한 게 공개키 방식을 사용한다.
공개키 방식은 각 사용자가 두 개의 키를 부여받는데, 하나 (공개키, public key) 는 공개되고 다른 하나 (개인키,비밀키 private key) 는 사용자에 의해 비밀리에 관리되야 한다.
뒤에 정리할 전자서명과 전자봉투의 원리를 이해하는데 제일 필요한 개념은 아래와 같다.

개인키로 암호화한건 공개키로 복호화 가능, 공개키로 암호화한건 개인키로 복호화 가능

이러한 원리로

  • 전자서명 (부인방지) : 개인키로 암호화한 것
  • 전자봉투 (데이터보안, 데이터를 암호화하고 싶을 때) : 공개키로 암호화한 것

공개키 암호 시스템의 대표적인 알고리즘은 RSA이다. RSA는 공개키 암호시스템의 하나로, 암호화뿐만 아니라 전자서명이 가능한 최초의 알고리즘으로 알려져있다. 위키백과



전자서명, 전자봉투에 대해

전자서명

전자서명이라 함은, 서명자를 확인하고 서명자가 당해 전자문서에 서명했다는 사실을 나타내는 데 이용하려고, 특정 전자문서에 첨부되거나 논리적으로 결합된 전자적 형태의 정보를 말한다.

공개 키 기반 구조(PKI) 기술측면에서 전자서명이란 전자문서의 해시(HASH)값을 서명자의 개인키(전자서명생성정보)로 변환(암호화)한 것으로서 RSA사에서 만든 PKCS#7 의 표준이 널리 사용되고 있다. 즉, 원래의 문서 내용을 A라고 하면 A의 해쉬 값을 잘 알려진 Hash 함수인 SHA1 같은 함수 하나를 정해 이런 Hash함수로 문서 A의 Hash 값을 구하고 이 Hash 값을, 보내는 사람(철수)의 Private Key 로 암호화 한다. 이런 다음 이렇게 암호화된 Hash값을 원래 문서 A 끝에 첨부하여 이 문서 전체를 받는 사람(영희)에게 보낸다. 출처

전자봉투

전자봉투(電子封套, digital envelope)란 대칭키를 사용하여 문서의 내용을 암호화한 후 해당 키를 수신자의 공개키를 이용하여 비대칭키로 다시 암호화한 것을 말한다. 이를 통해 암호화 및 복호화 시간을 단축하면서도 수신자 이외에는 해당 문서에 접근할 수 없도록 함으로써 기밀보안을 보장한다. 전자봉투 아이디어는 대칭키 암호화와 비대칭키 암호화의 하이브리드 속에서 나왔다. 전자봉투는 기존 전자서명 방식에서 보안성이 더 향상된 형태이다. 디지털봉투라고도 한다. 출처


## 이해를 위한 이야기🐣 **클라이언트** 와 **서버** 가 있다고 가정하자. 다양한 클라이언트가 존재하지만, 브라우저라고 생각한다. 이 브라우저는 `https://heeworld.unknownsite.com`에 접속하고 싶다. 그런데 https통신을 위해서는 http통신에 비해 보안절차가 더 필요하다. 내가 request를 보낸 uri가 신뢰할만한 서버(?)인지 확인이 필요한 것이다.
  1. 클라이언트가 서버에 인증서를 요청한다.
  2. 서버가 인증서를 클라이언트에게 보낸다. (믿을만한지 아닌지는 인증서에 따라 다르지.)
  3. 클라이언트는 서버가 보낸 인증서가 믿을만한 인증서인지 확인 후 통신을 시작한다.
    ❗️여기서 중요❗️
    1. 클라이언트는 신뢰할 만한 인증기관(Root CA)이나 중간 인증기관 의 정보를 가지고 있다.
    2. 클라이언트는 이 인증기관들의 공개키를 가지고 있으며, 서버가 보낸 인증서가 어디서 발급된 건지 확인한 후 자신이 알고 있는 공개키로 인증서에 있는 전자서명을 복호화 한다.
    3. 그럼 hash값이 툭 튀어나오는데, 인증서의 다른 정보를 동일한 hash 함수로 hash값을 만들고 두 hash값이 똑같은 지 비교 한다.
    4. 만약 값이 같으면 이건 신뢰할만한 인증기관에서 발급한거네! 라고 클라이언트가 인식하고 통신을 시작하지 한다. 값이 같지 않으면 신뢰할 수 없는 사이트라는 경고를 띄워준다.

인증서엔 무슨 내용이?

cert에 issue정보, subject정보, 공개키정보, serial number 등의 내용과 전자서명정보(sign) (중요!) 을 포함하고 있다.

hash 값을 뜨자

해시 함수의 가장 기본적인 성질은 두 해시 값이 다르다면 원래의 데이터도 다르다는 것이다. 이 특징은 해시 함수가 결정적이기 때문이다. 반대로 해시 함수는 단사 함수가 아니다. 같은 해시 값을 갖더라도 원래의 입력값이 같다는 것을 시사하지만 보장해주지는 않는다. 원래 입력의 한 비트만 바뀌더라도 해시 함수의 성질로 인해 해시 값은 크게 달라진다.

해시 함수는 임의의 길이를 갖는 메시지를 입력받아 고정된 길이의 해시값을 출력하는 함수이다. 암호 알고리즘에는 키가 사용되지만, 해시 함수는 키를 사용하지 않으므로 같은 입력에 대해서는 항상 같은 출력이 나오게 된다.

해시 함수는 어떤 입력 값에도 항상 고정된 길이의 해시값을 출력하고, 출력된 결과 값을 토대로 입력값을 유추할 수 없는 특징이 있다.

이 전자서명은 ROOT CA가 cert에 있는 sign 정보를 제외하고 모든 정보를 hash를 뜸 - sha256 etc. (개인키로 암호화) 그 hash값을 개인키로 암호화한 값을 전자서명으로 붙여서 cert를 발행! client는 이 cert의 전자서명을 공개키로 복호하하고, 나온 hash 값과 cert에 있는 정보 hash (sha 같은것)뜬걸 비교해서 판별

통신을 시작하지

전자봉투. 매번 통신할 때마다 인증서를 확인할 수 없으니 데이터를 보낼 때 대칭키를 공개키로 암호화해서 데이터랑 같이 던진다! (이 때 데이터는 대칭키로 암호화한 것) 서버는 공개키로 암호화된 대칭키를 개인키로 복호화해서 대칭키를 얻어내고, 그 데이터를 대칭키로 복호화해서 정보를 갖는다.


Written by@heeye
Work for a financial company as a Backend developer & Cloud engineer😌

GitHub