HMAC 인증이란? - REST API의 보안


안녕하세요! HMAC 인증 이라는게 참 처음접하면 이게 어떤 원리로 동작하는건지 혼란스러운데, 찾아보니 영어로는 쉽게 잘 설명해주는 글들이 많은데 한국어로는 쉬운 설명이 정말 거의 없더라구요. 그래서 제가 하나 적어보기로 했습니다.

HMAC을 사용하는 목적

REST API가 요청을 받았을 때, 이 요청이 신뢰할 수 있는 호출인지 확인하는 방법으로 HMAC을 사용합니다. 즉 이 요청이 해커에게서 온 부적절한 요청인지, 또는 정상적으로 요청된 것인지 확인할 수 있습니다. API 응답에 회원정보 같은 민감한 내용이 포함되어 있는 경우, 요청에 대한 인증도 없이 아무에게나 중요한 정보를 주면 안되겠죠.

지난번에 포스팅한 보안의 기본! 인증과 권한 개념에서 설명드렸듯이 서버에게서 자원을 받아내려면 인증과 권한 과정을 거쳐야 합니다. REST API에서는 서버에 요청을 보내는 행위자체가 자원을 요구하는 것이고, 이에 대한 인증/권한 과정을 구현하는 여러 방식중에 하나가 HMAC 입니다.

How Does It Work?

hmac

자잘하고 어려운 설명 보다 쉽게 큰 그림을 먼저 봅시다. 전체 인증 과정을 먼저 간략하게 설명드릴게요.

  1. 해쉬 생성 : 클라이언트는 key + message를 HMAC 알고리즘으로 처리하여 hash 값을 만들어냅니다.
  2. 요청 보내기 : 생성된 hash와 message를 HTTP 요청으로 REST API서버에게 보냅니다. 보통 hash는 HTTP 헤더 또는 url에 포함됩니다.
  3. 해쉬 생성 : 서버는 클라에게서 받은 요청 내의 message와 본인이 가지고있던 key를 조합하여 HMAC으로 hash값을 생성합니다.
  4. 비교 : 클라에서 넘어온 hash와 서버에서 생성된 hash가 동일한지 비교합니다. 동일하면 인증 성공입니다.

#KEY?

서버와 클라이언트는 각자 key 값을 알고 있습니다. 예를들어 "abcdef12345"와 같은 문자, 숫자, 특수기호등의 조합이겠죠. 이 값을 서버 어플리케이션과 클라이언트 어플리케이션이 각각 저장해두고 있습니다. 해커가 클라이언트의 요청을 중간에서 가로챘을 때 message는 알아도 이 key 값은 절대 알 수 없습니다. key 값을 모르니 임의로 hash를 생성해서 정상적인 클라이언트인 척 할 수가 없겠죠.

#MESSAGE?

hmac message는 '클라이언트가 보내는 요청 내용의 전문'이 될 수도, 아니면 단지 URL만이 될수도, 요청 내용 이외에 unix timestamp와 같은 다른 정보를 포함할 수도 있습니다. 이것은 인증방식 만드는 사람이 정하기 나름입니다.

이해를 돕기 위한 예시로 우리 회사의 API 문서에서 일부를 발췌하자면, REST API 요청의 X-Authorization 헤더에 다음의 값을 포함하라고 합니다.

HMAC (algorithm:sha256, encoding:hex)

  • HMAC Message Data: RequestURI(도메인주소를 제외한 /부터) + Timestamp(UTC Microtime)
  • SecretKey: 별도로 제공

[TIP 1] 어떤 요청이 중간에 해커에게 가로채어져서 변조되었다면, 이 요청은 '무결성'이 보장되지 않았다고 합니다. 요청의 전체 메세지에 대한 무결성을 보장하고 싶다면 요청 내용의 전문을 가지고 hash를 생성하는 것이 좋습니다.

[TIP 2] 실제 클라에서 정상적으로 생성된 hash를 해커가 그대로 재사용하는 것을 막기 위해 hash를 생성할 때 timestamp를 포함하는 것이 좋습니다.

References