ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION641 / 1500
보안난이도 하핵심 답변

HMAC 비교에서 일반 문자열 비교를 피해야 하는 이유는 무엇인가요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

HMAC 태그는 일반 문자열 비교보다 길이를 먼저 검증한 뒤, 고정 시간 비교를 제공하는 보안 API로 비교하겠습니다. 일부 비교 구현은 앞에서부터 검사하다가 첫 불일치에서 종료하므로, 공격자가 반복 관측을 통해 일치한 접두사 길이와 관련된 시간 차이를 추론할 여지가 있습니다. 네트워크 환경에서는 잡음이 크지만, 비교 경계에 불필요한 신호를 남길 이유도 없습니다.

예를 들어 서버가 32바이트 HMAC을 hex로 64문자라고 계약했다면, 먼저 입력이 허용된 hex 형식이고 정확한 길이인지 확인한 뒤 같은 바이트 배열로 디코딩합니다. 그 후 언어가 제공하는 constant-time compare로 기대 태그와 계산 태그를 비교합니다. 길이가 다른 값을 무조건 같은 루프로 늘려 비교할지는 API 계약에 따르되, 짧은 접두사만 받아들이는 오류는 없어야 합니다. 태그를 base64와 hex로 혼용해 길이 검사를 우회하지 않도록 인코딩도 하나로 고정합니다.

이 비교는 canonicalization이나 키 보관을 대신하지 않습니다. 서버가 JSON을 잘못 재직렬화하면 constant-time으로 틀린 값을 비교할 뿐이고, 서명 키가 유출되면 공격자는 올바른 태그를 만들 수 있습니다. 또 태그가 맞아도 오래된 event ID나 허용 창 밖 timestamp라면 재생으로 거절해야 합니다. 테스트에서는 완전히 틀린 첫 바이트, 마지막 바이트만 틀린 태그, 길이 오류, 잘못된 encoding을 각각 확인하고 외부 응답은 과도하게 차별화하지 않겠습니다.

예를 들어 SHA-256 태그를 hex 64자로 받는 API에서 계산 결과는 32바이트이고 후보는 먼저 64자의 ASCII hex인지 검사합니다. 63자나 0x 접두사가 붙은 값은 디코딩 전에 거절하고, 정상적으로 32바이트가 된 두 값만 안전 비교 API에 넘깁니다. 길이가 다른 값을 접두사만 비교해 통과시키면 공격자가 짧은 태그를 제출할 수 있으므로 고정 길이 계약이 우선입니다. 첫 바이트가 틀린 태그와 마지막 바이트가 틀린 태그를 각각 보내 같은 외부 실패 범주가 나오는지 확인하되, 네트워크 지연만으로 원격 공격 가능성을 단정하지는 않습니다. constant-time 비교는 비교 루프의 신호를 줄이는 구현 선택일 뿐, 잘못된 raw body나 유출 키를 고치지 않습니다. 따라서 서버 응답·로그에서 unknown kid, bad encoding, bad MAC을 상세히 구분해 oracle로 노출하지 않고 내부 추적 정보로만 남깁니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 고정 길이·인코딩 검증과 constant-time compare를 순서대로 설명한다.
  • 비교 구현의 side-channel과 HMAC 입력·재생 검사를 분리한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • constant-time이면 모든 원격 timing 공격이 사라진다고 단정한다.
  • 길이가 다른 태그나 잘못된 인코딩을 접두사 비교로 허용한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

  • 사용 언어의 안전 비교 API가 길이 오류를 어떻게 처리하는지 어떻게 확인할까요?
  • 서버 응답·로그의 차이가 태그 유효성 oracle이 되지 않게 하려면 무엇을 묶을까요?

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

← 전체 질문 보기