HMAC
HMAC
HMAC (Hash-based Message Authentication Code) 은 데이터의 무결성과 진위성을 검증하기 위해 사용되는 암호화 기술입니다. 비밀 키와 암호화 해시 함수를 결합하여, 메시지가 중간에 변경되지 않았으며 신뢰할 수 있는 출처로부터 왔음을 확인하는 데 사용됩니다.
작동 원리
송신자 - 수신자 간에 미리 공유된 비밀 키를 기반으로 작동합니다.
생성 단계 (송신자 측)
원본 메시지와 비밀 키를 결합합니다.
이 결합된 값을 특정 해시 함수 (ex. SHA-256)를 사용하여 해시 → HMAC 값을 생성합니다.
송신자는 원본 메시지와 함께 생성된 HMAC 값을 수신자에게 전송합니다.
검증 단계 (수신자 측)
전송받은 원본 메시지를 공유된 비밀 키와 동일한 해시 함수를 이용하여 HMAC 값을 직접 계산합니다.
자체적으로 계산한 HMAC 값과 송신자로부터 받은 HMAC 값을 비교합니다.
두 값이 일치하면 메시지가 변조되지 않았고, 비밀 키를 공유한 신뢰할 수 있는 송신자로부터 왔음을 확신할 수 있습니다.
주요 특징 및 보안
무결성 보장: 메시지가 전송 과정에서 변경되었는지 여부를 확인할 수 있습니다. 공격자가 메시지를 수정하더라도 비밀 키를 모르기 때문에 유효한 HMAC 값을 새로 생성할 수 없습니다.
진위성 인증: HMAC 값은 공유된 비밀 키를 아는 사람만이 생성할 수 있으므로, 메시지를 보낸 주체가 신뢰할 수 있는 발신자임을 증명합니다.
다양한 해시 함수 활용: SHA-256, SHA-512, MD5 등 다양한 암호화 해시 함수를 선택하여 사용할 수 있습니다.
Length Extension 공격 방어: 내부적으로 메시지와 키를 두 번 해싱하는 복잡한 과정을 거치므로, 단순 해싱 방식의 취약점인 ‘길이 확장 공격’을 효과적으로 방어할 수 있습니다.
중요한 점은 HMAC은 메시지 자체를 암호화하는 것은 아니기 때문에, 데이터의 기밀성이 필요한 경우에는 별도로 추가적인 암호화 기법이 적용되어야 합니다.
주요 사용 사례
API 인증: REST API와 같은 클라이언트와 서버 간의 통신에서 요청의 유효성을 검증하는 데 사용됩니다.
데이터 무결성 보호: 금융 거래나 온라인 결제 시스템과 같이 데이터의 위변조가 민감한 시스템에서 데이터 무결성을 보장하기 위해 사용됩니다.
보안 프로토콜: HTTPS, FTPS, SFTP와 같은 보안 통신 프로토콜에 통합되어 데이터 전송의 안정성을 높입니다.
토큰 기반 인증: JWT와 같은 토큰 기반 인증 시스템에서 토큰의 위변조를 방지하는 데 활용됩니다.
HMAC을 사용하는 이유
기밀성이 아닌, 무결성과 진위성을 보장하기 위함!
Gemini가 알려준 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
편지에 찍는 '밀랍 인장'을 생각해보세요.
HMAC을 이해하는 가장 좋은 비유는 중세 시대 편지에 찍던 '밀랍 인장'입니다.
- 편지 내용 (Data): 원본 파일(이미지, 동영상 등)의 URL
- 편지 봉투 (Encryption): HTTPS (SSL/TLS)
- 밀랍 인장 (HMAC): HMAC 값
- 인장을 찍는 도장 (Secret Key): 나만 가지고 있는 HMAC 비밀 키
1. 기밀성 (Confidentiality):
- 편지 내용을 다른 사람이 못 보게 하려면, 편지를 암호화하거나 자물쇠가 달린 상자에 넣어야 합니다. 이것이 바로 암호화의 역할입니다.
- 웹에서는 HTTPS가 이 역할을 합니다. 사용자와 서버 간의 모든 통신(URL 포함)을 암호화하여 중간에서 누가 훔쳐봐도 내용을 알 수 없게 만듭니다.
2. 무결성 & 진위성 (Integrity & Authenticity):
- 편지를 보냈는데, 받는 사람이 "이 편지가 중간에 뜯겨서 내용이 바뀌지 않았을까?" 또는 "이 편지를 정말 네가 보낸 게 맞을까?"를 확인하고 싶어 합니다.
- 이때 사용하는 것이 바로 밀랍 인장(HMAC)입니다.
- 나만 가지고 있는 고유한 도장(비밀 키)으로 인장을 찍어 보내면, 받는 사람은 인장이 훼손되지 않았는지 보고 (무결성 확인), 그 인장 모양이 내 것이 맞는지 확인하여 (진위성 확인) 편지를 신뢰할 수 있습니다.
GCS CDN 인증 사례
현재 GCS에 연결되어 있는 CDN에 서비스 계정을 이용하여 HMAC 인증을 적용해두었습니다. 하지만 이 구조로는 CDN URL이 탈취되면 원본 파일도 탈취되는 구조이기 때문에 HMAC을 사용하는 이유가 이해가 되지 않았습니다.
HMAC이 막으려는 공격은 이것과 다릅니다. 만약 HMAC이 없다면 아래의 공격이 가능합니다.
- URL 변조
- URL에는 GCS Object Path를 유추할 수 있는 path 값이 들어있습니다. (ex. {domain}/{folder}/{uuid}.png)
- folder 또는 uuid, id 등의 값을 바꾸어 다른 리소스에 접근을 시도할 수 있습니다.
- 사용자 위장
- path에 user id가 들어가는 경우, 이 값을 바꾸어 다른 사용자인 척 접근할 수 있습니다.
GCS에서 HMAC을 사용하면 Signed URL을 생성합니다. (ex. https://my-cdn.com/videos/episode1.mp4?Expires=1678886400&Signature= [HMAC값])
- 진위성 보장
- 이 URL을 생성할 수 있는 주체는 비밀 키를 가진 서버뿐입니다. 즉 이 URL 자체가 서버가 “이 사용자에게 이 파일에 대해 특정 시간까지 접근을 허용합니다.” 라고 서명해준 것과 같습니다.
- 무결성 보장
- 공격자가 URL의 일부를 바꾸려고 시도한 경우, CDN 서버는 URL과 자신이 가진 비밀 키를 조합하여 HMAC 값을 다시 계산합니다.
- 공격자가 변경한 URL로 계산된 HMAC 값과 원래 URL에 포함된 Signature 값이 다를 것입니다.
- 결국 CDN 서버는 요청이 중간에 변경되었다고 판단하고 요청을 거부 (403) 합니다.
걱정했던 CDN URL 탈취로 인한 유출을 막기 위해 짧은 만료 시간과 HTTPS를 함께 사용합니다.