AES-GCM은 메시지의 기밀성을 보호하고 무단 변경을 탐지할 수 있습니다. 하지만 그 자체만으로는 다른 면에서 유효한 메시지가 이미 처리되었는지를 수신자에게 알려 주지 않습니다.
혼동하기 쉬운 요구사항은 세 가지입니다. 암호화 시 고유한 키/nonce 쌍, 메시지와 그 맥락의 인증, 프로토콜 수준의 재전송 공격 처리입니다. HKDF는 키 파생을 도울 수 있지만 세 가지 모두를 자동으로 충족하지는 않습니다.
Nonce 재사용과 재전송 공격은 서로 다른 사건입니다
| 사건 | 발생하는 일 | 필요한 보호 |
|---|---|---|
| 암호화 중 nonce 재사용 | 서로 다른 평문을 같은 GCM 키와 nonce로 암호화함 | 신뢰할 수 있는 키/nonce 할당 전략 |
| 변조 | 암호문 또는 인증된 맥락이 변경됨 | 인증 복호화와 검증 실패 시 거부 |
| 재전송 공격 | 이전에 유효했던 암호화 메시지가 다시 전달됨 | 중복 또는 오래된 메시지를 인식하는 상태와 애플리케이션 규칙 |
| 순서 변경 | 유효한 메시지가 다른 순서로 도착함 | 프로토콜이 정한 순서 규칙과 범위를 제한한 순서 외 처리 |
다시 전달된 암호문에도 유효한 인증 태그가 있을 수 있습니다. 아무것도 바뀌지 않았기 때문입니다. 따라서 모든 중복 메시지가 자동으로 AES-GCM 인증에 실패한다는 말은 틀립니다. RFC 5116은 AEAD 인터페이스와 재전송 공격 방지 서비스를 명확히 구분합니다.
키와 nonce 쌍이 반복되면 안 되는 이유
GCM의 nonce는 비밀일 필요는 없지만, 주어진 키 아래에서 해당 방식의 고유성 요구사항을 충족해야 합니다. 96비트, 즉 12바이트 nonce가 일반적이지만 그 길이를 선택하는 것만으로 올바른 생성이 보장되지는 않습니다.
서로 다른 평문에 같은 키와 nonce를 재사용하면 암호화 키스트림을 재사용하게 되어 평문 사이의 관계가 노출됩니다. 진정성을 훼손하고 위조를 가능하게 할 수도 있습니다. 영향은 심각하지만, 계정의 모든 과거 키나 모든 메시지가 자동으로 드러난다고 설명해서는 안 됩니다. 영향 범위는 재사용한 키와 프로토콜에 따라 달라집니다.
NIST SP 800-38D는 GCM과 그 요구사항을 정의합니다. 구현은 ‘이 메시지 수까지는 안전하다’는 단순한 경험칙이 아니라, 적용되는 호출 횟수 제한과 nonce 생성 규칙을 따라야 합니다.
HKDF가 기여하는 것
RFC 5869에 명시된 HKDF는 추출과 확장 단계를 통해 입력 비밀 자료에서 키 자료를 파생합니다. 프로토콜은 맥락 레이블과 서로 다른 입력을 사용해 용도별 키를 분리할 수 있습니다.
HKDF는 결정적입니다. 충돌하거나 상태가 롤백된 클라이언트가 동일한 상태와 입력을 반복하면 동일한 출력을 다시 파생할 수 있습니다. 따라서 설계에 HKDF를 추가한다고 nonce 재사용이 불가능해지지는 않습니다.
메시지별 키는 하나의 키로 보호하는 내용의 양을 줄일 수 있지만, 안전한 상태 진행과 키 분리 및 삭제는 여전히 중요합니다. 실제로 서로 다른 키 아래에서 같은 nonce 값을 쓰는 것은 키/nonce 쌍을 반복하는 것과 같은 실패가 아닙니다. 프로토콜은 키가 실제로 다르다는 것을 확립해야 합니다.
재전송 공격 방지는 프로토콜의 역할입니다
수신자는 메시지 식별자, 시퀀스 위치, 세션 에포크 또는 이미 사용한 래칫 키를 추적할 수 있습니다. 공격자가 오래된 메시지에 새 메시지라는 꼬리표를 붙일 수 없도록 관련 필드를 인증해야 합니다.
그다음 애플리케이션은 중복이 무엇을 의미하는지 결정해야 합니다. 중복 채팅 말풍선은 불편하지만 같은 동작을 두 번 실행하면 더 심각할 수 있습니다. 네트워크 재시도는 흔하므로 암호학적 검사와 더불어 멱등 처리가 필요한 경우가 많습니다.
프로토콜이 그런 동작을 정하지 않았다면 모든 유효한 메시지가 엄격히 순서대로 도착하도록 요구하지 마세요. 모바일 클라이언트는 일상적으로 재연결하고 재시도하며 지연 메시지를 받습니다. 안전한 처리는 정당하게 늦게 도착한 메시지와 이미 처리했거나 맥락이 잘못된 메시지를 구분합니다.
보호를 주장하기 전에 테스트할 사항
- Nonce 할당 후 전송 기록 전에 재시작합니다. 같은 할당이 반복될 수 있나요?
- 더 오래된 상태 스냅샷을 복원합니다. 키, 카운터 또는 재전송 기록이 롤백될 수 있나요?
- 두 작업자나 기기에서 동시에 전송합니다. 키/nonce 도메인이 분리되어 있나요?
- 같은 유효한 메시지를 두 번 전달합니다. 애플리케이션 동작은 한 번만 실행되나요?
- 세션 식별자나 헤더를 바꿉니다. 맥락이 암호학적으로 결합되어 있나요?
- 유효한 메시지를 순서와 다르게 전달합니다. 오래된 상태를 받아들이지 않으면서 지원되는 지연을 처리하나요?
인증 복호화 API는 검증에 성공한 경우에만 평문을 애플리케이션에 반환해야 합니다. 이는 인터페이스 요구사항이며, 어떤 구현도 내부에서 임시 평문 버퍼를 계산하지 않는다는 주장은 아닙니다.
Livara의 주장을 정확하게 읽기
Livara의 보안 문서는 AES-256-GCM, 메시지별 체인, LVR1/LGS1 맥락을 언급합니다. 이러한 기본 요소만으로 올바른 충돌 복구, nonce 할당 또는 재전송 거부가 독립적으로 증명되지는 않습니다. 그런 주장에는 버전이 명시된 프로토콜 세부사항과 테스트 증거가 필요합니다.
견고한 설계는 역할을 명확히 나눕니다. 키 파생은 의도한 키를 만들고, AEAD는 내용과 맥락을 인증하며, 상태를 유지하는 프로토콜 로직은 유효한 메시지를 지금 받아들여도 되는지 판단합니다.



