1 पॉइंट द्वारा GN⁺ 2024-06-30 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • XAES-256-GCM एक नया AEAD specification है जो high-level encryption APIs में nonce management को कम जोखिमभरा बनाने के लिए 256-bit key और 192-bit nonce का उपयोग करता है
  • बड़ा nonce हर message के लिए operating system CSPRNG से अपने-आप नया मान बनाने वाला तरीका संभव बनाता है, और 2⁸⁰ messages पर collision risk को 2⁻³² स्तर पर रखने का लक्ष्य रखता है
  • अंदरूनी तौर पर यह input key और बड़े nonce से derived key और 96-bit nonce बनाकर standard AES-256-GCM को ज्यों का त्यों इस्तेमाल करने वाली extended nonce construction है
  • Go reference implementation crypto/cipher और crypto/aes भर से 100 lines से कम में आ जाती है, और प्रति message 3 AES-256 calls में से कुछ को precompute किया जा सकता है
  • FIPS 140 compliance और library compatibility को महत्व देते हुए, यह XChaCha20Poly1305 और AES-GCM-SIV के साथ nonce-less AEAD API के उम्मीदवार के रूप में इस्तेमाल हो सकता है

High-level API के लिए बड़ा nonce AEAD

  • XAES-256-GCM एक additional authenticated data के साथ authenticated encryption (AEAD) algorithm है, जो 256-bit key और 192-bit nonce का उपयोग करता है
  • design goals को तीन बिंदुओं में समेटा जा सकता है
    • लगभग असीमित message count पर भी random generation के लिए सुरक्षित बड़ा nonce support
    • पूर्ण और प्रत्यक्ष FIPS 140 compliance
    • सामान्य cryptography libraries के ऊपर आसान implementation
  • बड़े nonce की वजह से ऐसा API बनाया जा सकता है जिसमें user को birthday bound की गणना खुद न करनी पड़े, और हर message पर operating system CSPRNG से नया nonce पढ़ा जाए
  • compliance और compatibility को प्राथमिकता देने के कारण, यह उन environments में भी लागू किया जा सकता है जहाँ दूसरे बड़े nonce AEADs का उपयोग करना कठिन हो, लेकिन AEAD की जरूरत हो

AES-256-GCM को ज्यों का त्यों उपयोग करने वाली extended nonce construction

  • XAES-256-GCM, XChaCha20Poly1305 की तरह, मौजूदा AEAD के ऊपर बनी एक extended nonce construction है
  • input key और 192-bit nonce से internal AES-256-GCM के लिए derived key और derived nonce की गणना की जाती है
    • input key और nonce क्रमशः K, N
    • derived AES-256-GCM key और nonce Kₓ, Nₓ
  • AES-256ₖ call और nonce के शुरुआती हिस्से से Kₓ बनाया जाता है, और input nonce के आखिरी 96 bits को Nₓ के रूप में उपयोग किया जाता है
  • प्रति message AES-256ₖ call 3 बार चाहिए
    • इनमें से एक को दिए गए key के लिए precompute किया जा सकता है
    • बाकी दो calls वही key schedule reuse कर सकते हैं

implementation छोटी है और standard components से व्यक्त की जा सकती है

  • Go reference implementation precompute optimization और ज़्यादातर boilerplate सहित 100 lines से कम है
  • Go implementation केवल standard library के crypto/cipher और crypto/aes का उपयोग करती है
  • XAES-256-GCM को standard NIST SP 800-108r1 KDF और standard NIST AES-256-GCM AEAD के रूप में भी व्यक्त किया जा सकता है
    • KDF एक counter-based KDF है
    • PRF, CMAC-AES256 है
    • input key Kin है
    • label ASCII character X, यानी 0x58 है
    • context input nonce के पहले 96 bits हैं
    • counter size 16-bit है
    • optional L field को छोड़ा जाता है
    • output 256-bit derived key है
  • derived key और input nonce के आखिरी 96 bits को AES-256-GCM में दिया जाता है
  • parameters के चयन की वजह से, KDF और CMAC abstractions हटाने पर यह सिर्फ counter पर AES-256 call करने वाले तरीके से थोड़ा ही अधिक धीमा और जटिल है
  • यही parameters high-level OpenSSL API में भी supported हैं

third-party implementations और test vectors

  • 2024-06-29 के edit के अनुसार third-party implementations जोड़ी गई हैं
  • Web Cryptography API implementation 256-bit AES-CBC CryptoKey का उपयोग करती है
  • specification में दो मुख्य code paths के लिए test vectors शामिल हैं
    • MSB₁(L) = 0
    • MSB₁(L) = 1
  • 10,000 या 1,000,000 random iterations को संक्षिप्त करने वाले accumulated test vectors भी दिए गए हैं

/11 को छोड़ना और alternatives

  • पहले की योजना में XAES-256-GCM/11 नाम था, लेकिन अंतिम specification में /11 को छोड़ दिया गया
  • /11 एक performance optimization था, और AES-GCM इस्तेमाल करने का एक कारण FIPS 140 compliance है, इसलिए rounds बदलने पर compliance खत्म हो जाती है
  • अगर FIPS 140 compliance लक्ष्य न हो तो कई alternatives हैं
    • AES-GCM-SIV
    • AES core आधारित modern AEAD constructions
  • specification का Alternatives section हर alternative की XAES-256-GCM से तुलना करता है

Go और nonce-less AEAD API में इसकी जगह

  • XAES-256-GCM का लक्ष्य एक सुरक्षित, सीधा-सादा, compliant और interoperable AEAD है
  • इसका मुख्य उपयोग वही high-level API है जिसे Go में जोड़ा जाना वांछित है
  • XAES-256-GCM, XChaCha20Poly1305 और AES-GCM-SIV को पूरक करता है, और एक काल्पनिक nonce-less AEAD API implementation candidate के रूप में design किया गया है
  • क्योंकि Go standard library में केवल Go-विशिष्ट construction जोड़ना पसंद नहीं किया जाता, इसलिए दूसरे cryptography library maintainers की राय की जरूरत है

1 टिप्पणियां

 
GN⁺ 2024-06-30
Hacker News की राय
  • डिज़ाइन बहुत चतुर है: यह CMAC आधारित है, इसलिए निचले स्तर के primitives न होने पर भी AES-CBC से key derive की जा सकती है
    AES-CBC के नजरिए से इसे ऐसे देखा जा सकता है: L = AES-CBC-256ₖ(iv = 0¹²⁸, plaintext = 0¹²⁸)[:16] से शुरू करके K1 बनाते हैं, फिर M1, M2 को encrypt कर के Kₓ पाते हैं, और उसके बाद Nₓ = N[12:] इस्तेमाल करते हैं
    AES-CBC-256 को ऐसा मान सकते हैं कि वह ciphertext का सिर्फ पहला 128-bit block लौटाता है और padding block फेंक देता है; और अगर padding बंद नहीं कर सकते, तब भी lower-level implementation की तुलना में उसी key से AES calls सिर्फ 3 बार अधिक लगती हैं, इसलिए यह बुरा नहीं है
    इस गुण का इस्तेमाल करने वाला WebCrypto API आधारित JS implementation https://github.com/dchest/xaes पर है, और AES-CBC के लिए CryptoKey को सीधे स्वीकार करने तथा extractable=false के साथ IndexedDB में store करने जैसी CryptoKey विशेषताओं को भी support करता है

    • इस क्षेत्र में यह standard notation जैसा दिखता है, लेकिन सच कहूँ तो मुझे cryptography notation पसंद नहीं है
      उस pseudocode में आधी संख्याएँ bytes गिनती लगती हैं और बाकी आधी bits; अगर algorithm पहले से न पता हो तो कौन-सी कौन है, यह लगभग पता नहीं चलता
      उदाहरण के लिए N[:12] 12 bytes जैसा दिखता है, लेकिन 0¹²⁸ 16 bytes है, और X वास्तविक character 'X', यानी bit string 01011000 है, जबकि L bit string 01001100 नहीं बल्कि एक variable है
      साफ लगता है कि mathematicians को computer science वालों जितनी unambiguous notation पसंद नहीं है
    • 0¹²⁰10000111 जैसा डरावना दिखने वाला constant, CMAC में इस्तेमाल होने वाले underlying block cipher के block size b के लिए degree b वाले irreducible polynomials में, non-zero terms की न्यूनतम संख्या रखने वालों में lexicographic order में पहले polynomial के coefficients को दर्शाने वाली bit string है
      इसमें कोई छिपा हुआ इरादा नहीं है
    • मैं cryptography expert नहीं हूँ, लेकिन सार यह समझ में आता है कि standard AES-GCM AEAD में अगर अलग-अलग messages के लिए वही nonce दो बार इस्तेमाल हो जाए तो यह घातक रूप से टूट जाता है[1], और कई मामलों में nonce size भी random nonce को सुरक्षित रूप से इस्तेमाल करने के लिए छोटा है
      यह काम हर AES-GCM call में सिर्फ nonce ही नहीं, key भी बदलकर उस समस्या से आसानी से बचने देता है
      साथ ही, अगर AES-GCM उपलब्ध है तो यह आम तौर पर उपलब्ध “साधारण” AES ही इस्तेमाल करता है, और ऐसी नई जटिल constructions से बचता है जिनमें अभी कमजोरियाँ हो सकती हैं
      प्रति-message overhead बस “साधारण” AES से encrypt/decrypt किए जाने वाले दो छोटे buffers और थोड़ा लंबा 192-bit nonce है
      [1]: https://frereit.de/aes_gcm/
  • ऐसा लगता है कि यह vanilla AES-GCM की उस खामी को हटाता है जिसमें random nonce इस्तेमाल करने पर करीब हर 2^32 messages पर key rotate करनी पड़ती है
    AES-GCM में nonce collision घातक है, और कम-से-कम attacker को arbitrary messages sign करने की क्षमता दे देता है
    random nonce इस्तेमाल करना अनिवार्य नहीं है, लेकिन आम तौर पर recommend किया जाता है; और counter-based key derivation function व vanilla GCM जैसे दो primitives का उपयोग करके इसे FIPS compliant बनाना काफी चतुर है

    • सटीक कहें तो यह तरीका शुरू से ही random nonce को सुरक्षित बनाता है
      standard AES-GCM में 96-bit random collisions से बचने के लिए पर्याप्त नहीं है, इसलिए deterministic nonce generation इस्तेमाल करनी चाहिए
      साथ ही nonce चाहे जैसे बनाया गया हो, counter rollover हो जाता है और अगला block पहले block जैसा ही nonce+counter इस्तेमाल करने लगता है, इसलिए 2^32 blocks के बाद nonce या key बदलनी पड़ती है
  • वाकई शानदार। कुछ साल पहले जब मैंने आखिरी बार encrypted filesystem बनाया था, तब यह होता तो अच्छा होता
    बड़े पैमाने की filesystem deployments में nonce collision बड़ी चिंता है
    2^32 बड़ा लगता है, लेकिन PB-scale array में 100k IOPS प्रति सेकंड की दर से writes करते हुए और pseudorandom generator की randomness पर निर्भर रहते हुए collision की संभावना लगभग guaranteed हो जाती है

    • CAESAR competition[1] 2019 में खत्म हुई थी, और उसके परिणामस्वरूप पर्याप्त nonce space वाले कई AEAD निकले थे
      [1] https://en.m.wikipedia.org/wiki/CAESAR_Competition
    • लेकिन मुझे यह जानना है कि nonce collision समस्या क्यों है
      क्या इसका मतलब सिर्फ इतना नहीं कि दो blocks वही encryption key share करते हैं?
      अगर किसी भी block का plaintext पता नहीं है, तो यह system security को कैसे कमजोर करता है, समझ नहीं आता
  • archive file encryption के लिए किसी FIPS compliant age variant में इसका इस्तेमाल हो तो अच्छा होगा
    banking audits में age को इस use case के लिए इसलिए reject कर दिया गया क्योंकि वह ChaCha इस्तेमाल करता है, और age के X25519 public key वाले हिस्से को ठीक माना गया। मुझे लगा था कि X25519 को अपेक्षाकृत हाल ही में NIST approval मिला है
    Go का अनुभव नहीं है, लेकिन age spec देखकर लगता है कि इसे सीधे fit किया जा सकता है, और समय मिला तो कोशिश भी कर सकता हूँ
    नाम “compliant actually good encryption” के अर्थ में “cage” रखा जा सकता है
    1: https://github.com/FiloSottile/age

    • “compliant actually good encryption” शायद oxymoron भी हो सकता है
    • जाँचने पर लगता है कि Ed25519 approved है (FIPS 186-5), लेकिन X25519 अभी नहीं लगता
    • संदर्भ के लिए, Go standard library में अभी XAES implementation नहीं है, केवल C2SP का reference implementation है
    • bge, bureaucratic good encryption
  • एक non-cryptographer के रूप में जिज्ञासा है: 192-bit nonce क्यों, 256-bit क्यों नहीं, समझ नहीं आता
    practical applications में वे extra bits लागत जैसे लगेंगे, ऐसा नहीं लगता

    • 256 bits रखने की जगह नहीं है। 192 bits में lower nonce space से आने वाले 96 bits और जरूरी prefix के साथ 128-bit CMAC block में फिट होने वाले 96 bits शामिल हैं
      CMAC input को लंबा बनाया जा सकता है, लेकिन तब AES-256 block function को और कई बार चलाना पड़ेगा और CMAC key derivation function में झंझट वाले key-control issues भी आएँगे
      यह XChaCha20Poly1305 के 192-bit nonce इस्तेमाल करने के कारण जैसा ही है, और अन्य प्रमुख extended-nonce AEADs के साथ consistent होना भी एक हल्का फायदा है
  • कहा गया है “2⁸⁰ messages पर collision risk 2⁻³²”, लेकिन क्या AES block size सिर्फ 128 bits होने की वजह से उससे पहले समस्या नहीं आएगी?

    • अगर आप blocks पर birthday bound (https://sweet32.info) की बात कर रहे हैं, तो वह एक ही key से encrypted blocks की संख्या पर limit है
      XAES हर message के लिए बड़ी key derive करता है, इसलिए यह वह हासिल करता है जिसे अक्सर birthday bound से बेहतर guarantee कहा जाता है
    • नहीं
      आपको क्यों लगता है कि यह समस्या होगी, इसका और context न हो तो इससे ज्यादा विस्तार से जवाब देना मुश्किल है
  • “safe, boring, compliant, interoperable”
    मेरी सबसे पसंदीदा किस्म की technology है

  • अच्छा है। असल में NIST आधारित construction होना खुशी की बात है
    हालांकि NIST key derivation function की label और context जैसी कई खूबियाँ छोड़नी पड़ती हैं, यह थोड़ा अफसोसजनक है
    AES calls की संख्या कम करने के लिए यह sacrifice समझ में आता है, लेकिन खासकर सैकड़ों bytes से लंबे messages के लिए, कुछ AES calls बचाने की बजाय मैं मजबूत cryptographic separation को ज्यादा प्राथमिकता देता
    आखिर में, 96-bit से लंबे random GCM nonce को निश्चित रूप से बहुत गलत समझा जाता है, और वे 96-bit nonce की तुलना में बेहतर guarantees देते हैं[1]
    बेशक अगर हर message के लिए नई key derive कर सकते हैं, तो वह निश्चित रूप से बेहतर है
    [1] https://neilmadden.blog/2024/05/23/galois-counter-mode-and-r...