CodeKitHub
인코딩 도구

HMAC 생성기

마지막 업데이트:

이 도구는 비밀 키와 메시지로부터 HMAC(Hash-based Message Authentication Code)을 계산합니다. 기반 해시 함수로는 SHA-1, SHA-256, SHA-384, SHA-512를 사용할 수 있습니다. 일반 해시와 달리 HMAC은 공유 비밀 키를 필요로 하므로, 메시지가 그 키를 가진 사람으로부터 왔고 전송 중 변조되지 않았음을 증명합니다 — 그래서 API는 요청 서명에, 웹훅은 발신자 검증에 HMAC을 사용합니다. 모든 계산은 브라우저 내장 Web Crypto API를 통해 로컬에서 이루어지며, 비밀 키와 메시지는 어떤 서버로도 전송되지 않습니다.

HMAC-SHA1
HMAC-SHA256
HMAC-SHA384
HMAC-SHA512

이 도구는 무엇인가요?

HMAC은 Hash-based Message Authentication Code의 약자입니다. 비밀 키와 메시지, 그리고 SHA-256 같은 표준 해시 함수를 결합해 고정 길이의 다이제스트를 만듭니다. 같은 키와 메시지를 가진 사람이라면 누구나 정확히 같은 HMAC을 계산할 수 있지만, 키가 없다면 해시 알고리즘을 알고 있더라도 메시지에 대한 유효한 HMAC을 만들어내는 것은 계산적으로 불가능합니다.

이것이 일반 해시와의 핵심 차이입니다: 일반 해시(MD5, SHA-256 등)는 메시지만을 입력으로 받으므로 누구나 계산할 수 있고, 누가 만들었는지에 대해서는 아무것도 증명하지 못합니다. HMAC은 메시지*와* 비밀 키를 함께 받으므로, 유효한 HMAC은 발신자가 그 비밀 키를 가지고 있었음을 증명합니다 — 단순한 무결성 검사가 아니라 인증 메커니즘입니다.

HMAC은 NIST의 FIPS 198-1에서 공식 표준화되었고, 인터넷 프로토콜용으로는 IETF RFC 2104에 정의되어 있습니다. 이 도구는 브라우저 네이티브 Web Crypto API(`crypto.subtle.sign`을 HMAC 알고리즘으로 호출)로 HMAC을 계산하므로, 직접 구현한 자바스크립트 코드가 아니라 RFC 2104를 올바르게 구현한 엔진을 사용합니다.

왜 사용해야 할까요?

  • Stripe 웹훅 엔드포인트가 서명 불일치로 요청을 거부했고, 페이로드와 시크릿에서 HMAC-SHA256을 직접 다시 계산해 어디가 틀렸는지 찾아야 합니다.
  • 내부 API 연동 문서를 작성 중인데 외부 팀에게 보여줄 정확한 HMAC 예시가 필요하지만, 예시 하나 때문에 백엔드 스크립트를 실행하고 싶지는 않습니다.
  • 방금 작성한 Node.js나 Python HMAC 코드가 예상과 다른 결과를 내서, 어디가 버그인지 찾기 위해 다른 구현체의 독립적인 참조값이 필요합니다.
  • GitHub 웹훅 연동을 디버깅 중인데, 받은 X-Hub-Signature-256 헤더가 원본 페이로드와 웹훅 시크릿으로 계산한 HMAC과 일치하는지 확인해야 합니다.
  • 장애 대응 중 실제 운영 시크릿으로 즉시 HMAC을 생성해야 하는데, 그 시크릿을 어떤 제3자 서버로도 보내고 싶지 않습니다.
  • 100% 로컬 처리: 비밀 키와 메시지가 브라우저를 벗어나지 않으므로 실제 비밀 값을 테스트해도 안전합니다.

사용 방법

  1. "Secret Key" 필드에 비밀 키를 입력하세요.
  2. "Message" 필드에 인증하려는 메시지를 입력하세요.
  3. HMAC-SHA1, HMAC-SHA256, HMAC-SHA384, HMAC-SHA512 결과가 즉시 생성됩니다(대상 시스템이 대문자를 기대한다면 "Uppercase output"을 체크하세요).
  4. 필요한 HMAC 옆의 "Copy"를 클릭해 복사하세요.

예시

입력

Secret Key: key
Message: The quick brown fox jumps over the lazy dog

결과

HMAC-SHA256: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC-SHA1: de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9

이는 공개적으로 알려진 표준 테스트 벡터입니다: 키 "key"와 이 메시지 그대로라면 올바르게 구현된 모든 시스템에서 HMAC-SHA256과 HMAC-SHA1은 항상 이 값을 만들어내므로, 이 도구의 출력을 독립적으로 검증할 수 있습니다.

HMAC vs 일반 해시: 키가 필요한 순간

핵심 질문은 이것입니다: 이 다이제스트를 누가 만들었는지 증명해야 하는가, 아니면 내용이 변경되지 않았음만 확인하면 되는가? 다운로드한 파일이 배포자가 공개한 값과 일치하는지 확인하거나 레코드를 중복 제거하는 것처럼 공개 체크섬으로 충분하다면 일반 해시로 되고, 누구나 키 없이 확인할 수 있습니다. 반면 그 다이제스트가 특정 비밀을 가진 사람만이 만들어낼 수 있음을 증명해야 한다면 — API 호출자를 인증하거나 웹훅 발신자를 신뢰해야 한다면 — HMAC이 필요합니다. 일반 해시는 비밀을 전혀 모르는 공격자에게도 실제 발신자와 동일하게 유효한 다이제스트를 위조할 능력을 주기 때문입니다.

다중 알고리즘 해시 생성기 · JWT 디코더 · MD5 생성기

네 가지 HMAC 알고리즘 비교

네 알고리즘 모두 RFC 2104의 동일한 HMAC 구조를 사용하며, 차이는 기반 해시 함수와 그에 따른 출력 길이뿐입니다.

알고리즘출력 크기주요 용도
HMAC-SHA1160비트(16진수 40자)레거시 API, 구형 OAuth 1.0a 서명
HMAC-SHA256256비트(16진수 64자)API 요청 서명, JWT HS256, 웹훅 검증
HMAC-SHA384384비트(16진수 96자)더 긴 출력이 필요한 고신뢰 서명
HMAC-SHA512512비트(16진수 128자)고보안 애플리케이션을 위한 최대 길이 다이제스트

흔한 활용 사례

  • 공유 비밀로 나가는 API 요청에 서명해 서버가 호출자의 신원을 검증할 수 있게 합니다.
  • 들어오는 웹훅 페이로드를 검증합니다(Stripe-Signature, GitHub X-Hub-Signature-256 등의 헤더는 모두 HMAC-SHA256을 사용합니다).
  • HS256/HS384/HS512로 서명된 JWT의 서명 부분을 생성하고 검증합니다.
  • 서버 측 또는 클라이언트 측 HMAC 구현을 배포하기 전에 기대한 출력과 일치하는지 테스트합니다.

HMAC을 직접 구현할 때 흔히 저지르는 실수

"내 HMAC이 안 맞는다"는 문제의 대부분은 알고리즘을 잘못 골라서가 아니라, 계산 전에 키와 메시지를 준비하는 과정의 사소한 디테일에서 비롯됩니다.

  • 키가 양쪽에서 동일한 인코딩으로 처리되는지 확인하세요 — 일반 UTF-8 문자열과 디코딩된 hex/base64 문자열은 겉보기엔 비슷해 보여도 완전히 다른 HMAC을 만들어냅니다.
  • 웹훅 검증 시에는 항상 JSON 객체로 파싱되기 전의 원본 페이로드(raw body)로 HMAC을 계산하세요 — 많은 백엔드 프레임워크가 요청 본문을 자동으로 파싱하는데, 다시 문자열로 변환한 객체로 계산하면 키 순서나 공백이 발신자가 실제로 보낸 원본 본문과 달라질 수 있습니다.
  • 실제 프로덕션 코드에서 HMAC을 검증할 때는 항상 일반 `===` 대신 상수 시간(constant-time) 비교를 사용해 타이밍 공격을 방지하세요 — 이 도구는 디버깅 중 생성 및 육안 비교용일 뿐, 프로덕션 검증 로직을 대체하지 않습니다.

자주 묻는 질문

HMAC이란 무엇인가요?

HMAC(Hash-based Message Authentication Code)은 비밀 키와 메시지를 해시 함수로 결합해 메시지의 무결성과 발신자가 해당 키를 가지고 있음을 동시에 증명하는 다이제스트를 만듭니다. NIST FIPS 198-1과 IETF RFC 2104에 정의되어 있습니다.

HMAC과 일반 해시의 차이는 무엇인가요?

일반 해시(SHA-256, MD5 등)는 메시지만을 입력으로 받으므로 누구나 계산할 수 있고, 메시지가 손상되지 않았음만 증명할 뿐 누가 보냈는지는 증명하지 못합니다. HMAC은 메시지에 비밀 키를 더해 계산합니다: 특정 비밀을 가진 사람이 메시지를 보냈음을 증명해야 한다면(API 서명, 웹훅 발신자 검증 등) HMAC이 필요합니다. 파일이나 메시지가 변경되지 않았는지만 확인하면 되고 작성자 증명은 필요 없다면 일반 해시로 충분합니다.

제 비밀 키가 서버로 전송되나요?

아닙니다. 이 도구는 Web Crypto API를 사용해 HMAC을 브라우저 안에서만 계산합니다. 키와 메시지는 어디로도 전송되지 않으므로 실제 운영 환경의 비밀 값을 테스트해도 안전합니다.

SHA-1, SHA-256, SHA-384, SHA-512 중 어떤 알고리즘을 써야 하나요?

특정 시스템이 다른 것을 요구하지 않는 한 HMAC-SHA256을 사용하세요 — AWS, Stripe, GitHub 웹훅을 비롯한 대부분의 현대 API가 사용하는 사실상 표준이며 충분한 보안 여유를 제공합니다. HMAC-SHA1은 구형 OAuth 1.0a 같은 레거시 시스템에서 여전히 흔히 쓰이지만 기반 해시인 SHA-1 자체는 취약한 것으로 간주됩니다. HMAC-SHA384/512는 더 긴 출력이나 추가 보안 여유가 특별히 필요한 경우에 사용합니다.

일반 SHA-1이 깨졌다는데, HMAC-SHA1도 안전하지 않은가요?

2017년 SHA-1에 대한 충돌 공격은 일반 해시 함수로서의 SHA-1을 무너뜨렸지만, HMAC의 안전성은 충돌 저항성에 그런 방식으로 의존하지 않기 때문에 HMAC-SHA1은 여전히 암호학적으로 건전하다고 평가됩니다. 다만 새로 구축하는 시스템이라면 HMAC-SHA256 이상을 쓰는 것이 좋습니다 — 실질적인 단점이 없고 이런 논의 자체를 피할 수 있습니다.

HMAC의 실제 활용 사례는 무엇인가요?

REST API 요청에 서명해 서버가 호출자가 공유 API 비밀을 가지고 있음을 검증하게 하는 것, Stripe·GitHub·Shopify 같은 서비스의 웹훅 페이로드를 검증해 요청이 실제로 그곳에서 왔고 위조되지 않았음을 확인하는 것, 2단계 인증용 시간 기반 일회용 비밀번호(TOTP/HOTP)를 생성하는 것, 그리고 HS256/HS384/HS512 알고리즘으로 JWT 토큰에 서명하는 것 등이 있습니다.

코드에서 직접 계산한 HMAC이 이 도구의 결과와 다른 이유는 무엇인가요?

가장 흔한 원인은 메시지나 키의 인코딩 불일치입니다(예: 한쪽에서는 키를 UTF-8로, 다른 쪽에서는 hex로 처리하는 경우), 페이로드에 숨어 들어간 공백이나 줄바꿈(재포맷된 JSON을 복사-붙여넣기 할 때 흔히 발생), 또는 잘못된 환경의 키를 사용한 경우(스테이징 시크릿으로 프로덕션 페이로드를 검증하는 등)입니다. 알고리즘을 의심하기 전에 키와 메시지의 정확한 바이트 표현부터 확인하세요.

키와 메시지의 순서가 중요한가요? 서로 바꿔도 되나요?

임의로 바꿀 수 없습니다. HMAC은 RFC 2104에 따라 H(key XOR opad, H(key XOR ipad, message))로 구체적으로 정의되어 있습니다 — 키와 메시지는 이 구조 안에서 수학적으로 서로 다른 역할을 하며, 위치를 바꿀 수 있는 단순한 두 입력값이 아닙니다. 어느 것을 "키"로, 어느 것을 "메시지"로 쓸지 바꾸면 완전히 다른 HMAC이 나옵니다.

HMAC으로 데이터를 검증이 아니라 암호화할 수도 있나요?

아니요 — HMAC은 고정 길이 다이제스트를 만드는 단방향 함수이지 암호화 메커니즘이 아닙니다. HMAC을 "복호화"해서 원래 메시지를 되돌릴 수는 없습니다. HMAC은 이미 알고 있는 메시지의 무결성과 진위를 증명할 뿐, 내용을 숨기지는 않습니다. 암호화가 필요하다면 AES 같은 별도의 알고리즘이 필요합니다.

비밀 키가 해시 함수의 블록 크기보다 짧으면 어떻게 되나요?

RFC 2104에 따르면 키가 해시 함수의 내부 블록 크기(SHA-1/SHA-256은 64바이트, SHA-384/SHA-512는 128바이트)보다 짧을 경우, 계산에 사용되기 전에 블록 크기에 도달할 때까지 끝에 0 바이트가 채워집니다 — 이는 Web Crypto API가 자동으로 처리하므로 직접 패딩할 필요는 없습니다.

관련 도구