왜 만들었나요
쇼핑몰에 결제를 붙이면서 결제사 웹훅이 날아오기 시작했는데, 이게 정말 결제사가 보낸 건지 누가 흉내 내서 쏜 건지 서버 입장에선 구분할 방법이 없었습니다. 문서를 보니 "우리가 알려준 키로 본문을 서명한 값"을 헤더에 같이 보낸다더군요. 그 값이 맞는지 확인하려고 만들었습니다.
메시지와 비밀키로 서명값을 만듭니다. 결제사 웹훅이나 API 요청이 진짜인지 확인할 때 씁니다.
로딩 중...
쇼핑몰에 결제를 붙이면서 결제사 웹훅이 날아오기 시작했는데, 이게 정말 결제사가 보낸 건지 누가 흉내 내서 쏜 건지 서버 입장에선 구분할 방법이 없었습니다. 문서를 보니 "우리가 알려준 키로 본문을 서명한 값"을 헤더에 같이 보낸다더군요. 그 값이 맞는지 확인하려고 만들었습니다.
Note
입력한 메시지와 비밀키는 서버로 전송되지 않습니다. 계산이 전부 브라우저 안에서 이뤄져, 운영 중인 실제 키를 넣어 확인해도 기기 밖으로 나가지 않습니다.
위쪽 입력창에 서명할 메시지를 붙여넣고, 아래 키 칸에 비밀키를 입력합니다. 키가 Hex나 Base64 형태라면 왼쪽 토글로 형식을 바꿉니다.

알고리즘을 고릅니다. 결제·API 서명은 대부분 SHA256이라 기본값이 그걸로 잡혀 있습니다.

포맷에서 상대 시스템이 요구하는 출력 형식을 고르고 변환합니다. 검증할 서명이 있다면 비교 칸에 넣어 일치 여부를 확인합니다.

웹훅 본문과 비밀키를 넣으면 이렇게 나옵니다.
메시지 {"orderId":"A123","status":"paid"}
키 whsec_abc123
알고리즘 SHA256 / HEX
↓
서명 3f7a9c2e8b1d4f6a0c5e2b8d7f3a1c9e…
이 값이 요청 헤더로 온 서명과 같으면 진짜 결제사가 보낸 요청입니다.
해시는 아무나 계산할 수 있습니다. 메시지만 있으면 누구나 같은 값을 만들 수 있어서, 보낸 사람이 누구인지는 증명하지 못합니다.
HMAC은 여기에 비밀키를 섞습니다. 키를 아는 쪽만 올바른 값을 만들 수 있으므로, 값이 맞으면 "키를 가진 사람이 보냈고 내용도 안 바뀌었다"가 동시에 증명됩니다.
대개 메시지가 조금 다른 경우입니다.
보안 목적이라면 쓰지 마세요. 오래된 방식이라 안전하지 않습니다. 옛 시스템과 맞춰야 할 때만 쓰고, 새로 만드는 것은 SHA256 으로 하세요.
HMAC의 안전성은 키를 상대와 나만 안다는 데서 나옵니다. 코드에 그대로 적어 두거나 저장소에 올리면 서명이 아무 의미가 없어집니다.
메시지 + 비밀키로 만드는 서명값입니다. 키를 아는 쪽만 같은 값을 만들 수 있어서, 보낸 사람 확인과 위조 방지를 동시에 합니다.
어떤 일이 일어났을 때 상대 서버가 내 서버로 먼저 보내는 알림입니다. 결제 완료·배송 시작처럼 실시간으로 알아야 하는 일에 쓰이며, 아무나 흉내 낼 수 있기 때문에 서명 검증이 필요합니다.
일반 해시 H(message)는 메��지만 알면 누구나 계산할 수 있지만, HMAC은 비밀 키(Secret Key)를 함께 사용하여 키를 모르는 사람은 올바른 값을 생성할 수 없습니다. 이를 통해 메시지의 무결성(변조 여부)과 인증(발신자 확인)을 동시에 보장합니다.
GitHub, Stripe, Slack 등의 서비스는 Webhook 요청 시 헤더에 HMAC 서명을 포함합니다. 예를 들어 GitHub은 X-Hub-Signature-256 헤더에 HMAC-SHA256(secret, body) 값을 전달합니다. 수신 서버에서 동일한 방식으로 계산한 값과 비교하여 요청이 해당 서비스에서 온 것인지 검증합니다.
HMAC 키는 최소한 사용하는 해시 함수의 출력 길이 이상이어야 합니다. HMAC-SHA256이면 32바이트(256비트) 이상, HMAC-SHA512이면 64바이트(512비트) 이상을 권장합니다. 충분히 무작위한 값으로 생성해야 하며, 예측 가능한 문자열은 사용하지 마세요.
아니요, 모든 HMAC 연산은 브라우저 안에서 끝납니다. SHA 계열과 MD5·RIPEMD160은 자바스크립트 해시 구현으로, MD4는 WebAssembly 모듈로, DES·3DES·RC2 계열 MAC은 자바스크립트 암호 라이브러리로 계산하며 어느 경우에도 입력한 메시지와 비밀 키가 외부 서버로 전송되지 않습니다.
HMAC 검증 시 일반 문자열 비교(===)를 사용하면, 불일치 위치에 따라 응답 시간이 미세하게 달라집니다. 공격자가 이 시간 차이를 분석하여 한 바이트씩 올바른 HMAC 값을 추측할 수 있으며, 이를 Timing Attack이라 합니다. 서버 측 검증에서는 반드시 상수 시간 비교(Constant-time comparison)를 사용해야 합니다.
마지막 업데이트: 2026년 8월