HMAC 키가 해시 블록보다 길거나 출력 태그를 잘라 쓰면 어떤 규칙과 검증 길이를 합의해야 하나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
RFC 2104 규칙에 따라 해시 블록보다 긴 키는 먼저 선택한 해시로 해시한 결과를 HMAC 키로 사용하고, 출력 태그를 자를 때는 고정된 길이와 인코딩을 양쪽이 계약해야 합니다. 예를 들어 SHA-256의 블록 크기를 64바이트로 두고 100바이트 키를 넣으면 K' = SHA-256(K)인 32바이트 결과를 64바이트 블록으로 zero-pad한 뒤 ipad·opad 계산에 사용합니다. 애플리케이션이 긴 문자열을 그대로 별도 방식으로 자르면 RFC HMAC과 다른 MAC이 됩니다.
전체 SHA-256 태그가 32바이트인데 프로토콜이 앞의 16바이트만 전송하기로 했다면 서버는 정확히 16바이트를 디코딩하고 정확히 비교해야 합니다. t비트 truncation을 사용할 때는 그 길이를 문서·키 버전·테스트 벡터에 넣고, 임의 길이 접두사를 허용하지 않습니다. 태그를 짧게 할수록 한 번의 추측 성공 확률과 온라인 공격 예산의 곱이 커지므로, 길이는 표현 편의가 아니라 보안 목표에 맞춰 선택합니다.
여기서 HMAC이 맞아도 재생은 막히지 않습니다. 공격자가 같은 유효 요청을 반복할 수 있으므로 timestamp가 서명된 입력에 포함되는지 확인하고, 허용 창과 event ID·nonce의 저장 기간을 함께 둡니다. 예를 들어 5분 창을 허용하면서 event ID를 1분만 저장하면 같은 서명이 다시 효과를 낼 수 있습니다. 기존 이벤트가 같은 키로 재전송되는 정상 retry인지 구분하려면 내구 중복 마커를 사용하고, 키가 안전하다는 이유로 무제한 재전송을 허용하지 않겠습니다.
수치로 분리하면 계약을 점검하기 쉽습니다. SHA-256의 B=64바이트, L=32바이트일 때 100바이트 키는 먼저 32바이트 digest가 되고 32바이트 zero padding을 더해 64바이트 블록이 됩니다. 32바이트 전체 태그 대신 16바이트만 전송한다면 매 시도 성공 확률은 이상적으로 2^-128 수준으로 보지만, 공격자가 허용받는 q번 시도를 곱해 판단해야 하며 임의 길이 접두사는 허용하지 않습니다. 이것은 HMAC 계산 규칙입니다. 별도로 timestamp가 signature base에 포함되고 허용 창이 300초라면 event ID 또는 nonce의 중복 마커도 최소 그 창과 저장 지연을 덮어야 합니다. event ID를 60초만 저장하면 5분 안에 동일한 유효 요청을 다시 보낼 수 있습니다. 정상 retry인지 중복 공격인지의 업무 정책은 MAC이 증명하지 않으므로 원자적 insert-if-absent와 만료 정책으로 분리합니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- 긴 키 처리와 태그 truncation을 RFC 규칙·고정 길이로 설명한다.
- 짧은 태그의 추측 예산과 재생 방지를 별도 계산한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- 긴 키는 무조건 더 강하므로 아무 규칙 없이 직접 사용한다.
- 서명 태그가 맞으면 동일 payload의 재전송도 안전하다고 말한다.
- 서버가 임의 길이 prefix를 받아 주도록 구현한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- 선택한 해시 프로필의 블록 크기와 라이브러리 API를 어떻게 검증할까요?
- 키 회전 중 구 태그 길이와 신규 태그 길이를 함께 허용할지 무엇을 기준으로 정할까요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.