1P by neo 3달전 | favorite | 댓글 1개

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