# XAES-256-GCM 확장 논스 AEAD

> Clean Markdown view of GeekNews topic #15607. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=15607](https://news.hada.io/topic?id=15607)
- GeekNews Markdown: [https://news.hada.io/topic/15607.md](https://news.hada.io/topic/15607.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-06-30T10:14:05+09:00
- Updated: 2024-06-30T10:14:05+09:00
- Original source: [words.filippo.io](https://words.filippo.io/dispatches/xaes-256-gcm/)
- Points: 1
- Comments: 1

## Topic Body

##### 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와 같은 대안도 고려할 가치가 있음
- 새로운 기술을 도입할 때는 성능과 호환성을 신중히 검토해야 함

## Comments



### Comment 26797

- Author: neo
- Created: 2024-06-30T10:14:05+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=40826683) 
- 디자인이 매우 영리함: CMAC 기반으로, 낮은 수준의 프리미티브가 없을 때 AES-CBC를 사용하여 키를 유도할 수 있음
  - AES-CBC 용어로 설명하면:
    ```plaintext
    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 링크](https://github.com/dchest/xaes)
  - AES-CBC용으로 의도된 적절한 CryptoKey를 수용하며, IndexedDB에 저장 가능

- 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비트이기 때문에 그 전에 문제가 발생할 수 있는지 궁금함
