GN⁺: XAES-256-GCM 확장 논스 AEAD
(words.filippo.io)XAES-256-GCM 소개
- XAES-256-GCM은 256비트 키와 192비트 논스를 사용하는 인증된 암호화 알고리즘(AEAD)임
- 주요 목표:
- 무작위로 생성된 논스를 안전하게 지원
- FIPS 140 준수
- 일반적인 암호화 라이브러리에서 쉽게 구현 가능
XAES-256-GCM의 설계 목표
- 큰 논스를 사용하여 무제한 메시지에 대해 안전하게 무작위로 생성 가능
- FIPS 140 준수를 통해 다양한 환경에서 사용 가능
- 간단한 구현을 통해 사용자 부담을 줄임
XAES-256-GCM의 작동 원리
- AES-256-GCM을 기반으로 확장된 논스 구조 사용
- 입력 키와 논스를 사용하여 파생 키를 계산
- 세 번의 AES-256 호출로 메시지 처리
구현 및 최적화
- Go 참조 구현은 100줄 미만의 코드로 구성
- 표준 라이브러리의 crypto/cipher와 crypto/aes만 사용
- NIST SP 800-108r1 KDF와 NIST AES-256-GCM AEAD를 사용하여 설명 가능
타사 구현 및 호환성
- .NET 8+, pyca/cryptography, Web Cryptography API에서 타사 구현 존재
- FIPS 140 준수를 위해 라운드 수 변경 불가
대안 및 테스트 벡터
- AES-GCM-SIV 등 다양한 대안 존재
- 주요 코드 경로에 대한 테스트 벡터 포함
요약
- XAES-256-GCM은 안전하고 준수하며 상호 운용 가능한 AEAD로 설계됨
- XChaCha20Poly1305 및 AES-GCM-SIV를 보완하는 역할
- Go 표준 라이브러리에 추가되기를 희망
GN⁺의 의견
- XAES-256-GCM은 큰 논스를 사용하여 안전성을 높인 점이 주목할 만함
- FIPS 140 준수를 통해 다양한 환경에서 사용 가능
- Go와 같은 언어에서 쉽게 구현할 수 있어 개발자에게 유용함
- AES-GCM-SIV와 같은 대안도 고려할 가치가 있음
- 새로운 기술을 도입할 때는 성능과 호환성을 신중히 검토해야 함
Hacker News 의견
-
디자인이 매우 영리함: CMAC 기반으로, 낮은 수준의 프리미티브가 없을 때 AES-CBC를 사용하여 키를 유도할 수 있음
- AES-CBC 용어로 설명하면:
1. L = AES-CBC-256ₖ(iv = 0¹²⁸, plaintext = 0¹²⁸)[:16] 2. MSB₁(L) = 0이면, K1 = L << 1; 그렇지 않으면 K1 = (L << 1) ⊕ 0¹²⁰10000111 3. M1 = 0x00 || 0x01 || X || 0x00 || N[:12] 4. M2 = 0x00 || 0x02 || X || 0x00 || N[:12] 5. Kₓ = AES-CBC-256ₖ(iv = K1, plaintext = M1)[:16] || AES-CBC-256ₖ(iv = K1, plaintext = M2)[:16] 6. Nₓ = N[12:]
- AES-CBC-256은 첫 번째 128비트 블록을 반환하고, 패딩된 블록은 버림
- 키를 유도한 후 표준 AES-GCM과 함께 사용
- WebCrypto API를 기반으로 한 JS 구현 예시: GitHub 링크
- AES-CBC용으로 의도된 적절한 CryptoKey를 수용하며, IndexedDB에 저장 가능
- AES-CBC 용어로 설명하면:
-
Filippo의 작업이 훌륭함: 무작위 논스를 사용할 경우 약 2^32 메시지마다 키를 회전해야 하는 문제를 해결함
- AES-GCM에서 논스 충돌은 치명적임 (공격자가 임의의 메시지에 서명할 수 있게 됨)
- 무작위 논스를 사용할 필요는 없지만 일반적으로 권장됨
- 두 가지 프리미티브(카운터 기반 KDF와 일반 GCM)를 사용하여 FIPS 준수하게 만든 것이 매우 영리함
-
이 기능이 몇 년 전 암호화 파일 시스템을 작성할 때 존재했으면 좋았을 것임
- 논스 충돌은 대규모 파일 시스템 배포에서 큰 문제임
- 2^32는 커 보이지만 초당 100k IOPS를 쓰는 PB 배열에서는 PRNG 무작위성에 의존할 경우 충돌 가능성이 거의 보장됨
-
이 기능이 아카이브 파일 암호화 용도로 FIPS 준수 변형 age[1]에 사용되기를 바람
- 은행 산업 감사관들이 ChaCha 대신 AES를 사용하지 않아 age를 반대했음 (X25519 공개 키 부분은 NIST에서 최근 승인됨)
- golang 경험은 없지만 age 사양에 따라 쉽게 적용될 것 같음
- 시간이 허락하면 시도해볼 것임
- "cage"라고 부를 것임 ("compliant actually good encryption"의 약자)
-
비암호학자의 질문: 왜 192비트 논스를 사용하고 256비트를 사용하지 않는지 궁금함
- 실용적인 응용에서 추가 비트가 비용이 많이 들 것 같지 않음
-
(2⁸⁰ 메시지에서 충돌 위험 2⁻³²)
- AES 블록 크기가 128비트이기 때문에 그 전에 문제가 발생할 수 있는지 궁금함