2 पॉइंट द्वारा GN⁺ 2024-05-08 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Go 1.22 में मौजूदा math/rand पैकेज और नए पेश किए गए math/rand/v2 पैकेज, दोनों में cryptographically secure random number generator का उपयोग करने के लिए बदलाव किया गया है। इससे बेहतर randomness मिलती है, और जब developer गलती से crypto/rand की जगह math/rand का उपयोग कर लेते हैं, तब होने वाले नुकसान को काफी कम किया जा सकता है.

सांख्यिकीय randomness और cryptographic randomness का अंतर

  • सांख्यिकीय randomness simulation, sampling, numerical analysis, non-cryptographic random algorithms, random testing, input shuffling, random exponential backoff आदि के लिए उपयुक्त है.
  • बहुत बुनियादी और आसानी से गणना किए जा सकने वाले गणितीय फ़ॉर्मूले भी इन उपयोगों के लिए काफ़ी अच्छे से काम करते हैं. लेकिन इस्तेमाल किए गए algorithm को जानने वाला observer कुछ निश्चित मान देखने के बाद आगे की sequence का अनुमान लगा सकता है.
  • Cryptographic randomness ऐसी होनी चाहिए कि पहले बने हुए कितने भी मानों को देखने के बाद भी वह व्यवहारिक रूप से पूरी तरह अप्रत्याशित रहे.
  • सुरक्षित cryptographic protocol, secret key, modern commerce और online privacy आदि cryptographic randomness पर बहुत अधिक निर्भर करते हैं.

Go 1 का math/rand generator

  • यह Linear-feedback shift register(LFSR) तरीका इस्तेमाल करता है.
  • इसमें internal state, 607 uint64 से बने vector के रूप में पूरी तरह उजागर हो जाने की समस्या है.
  • Generator से 607 मान पढ़ लेने पर पूरी state उजागर हो जाती है और उसके बाद के मानों का अनुमान लगाया जा सकता है.

math/rand/v2 का PCG generator

  • Melissa O'Neill के PCG algorithm का उपयोग करता है. यह 128-bit LCG पर post-processing लागू करने वाला तरीका है.
  • इसकी पूरी state एक 128-bit संख्या होती है, और update 128-bit multiplication और addition से होता है.
  • Go में O'Neill के प्रस्ताव के अनुसार XOR-आधारित तरीके की जगह multiplication-आधारित scramble function का उपयोग किया गया है, ताकि bits अधिक आक्रामक ढंग से mix हों.
  • यह Go 1 generator से अधिक computation मांगता है, लेकिन state store करने के लिए memory बहुत कम चाहिए, initial state value के प्रति कम संवेदनशील है, और उन statistical tests को भी pass करता है जिनमें दूसरे generator असफल हो जाते हैं.
  • लेकिन PCG भी अब भी वास्तव में अप्रत्याशित नहीं है.

Cryptographic randomness

  • अंततः operating system को physical device के noise से वास्तविक randomness इकट्ठा करनी होती है.
  • पर्याप्त randomness (256-bit या उससे अधिक) इकट्ठा होने पर, उसे cryptographic hash या encryption algorithm से expand करके मनचाही लंबाई की random sequence बनाई जा सकती है.
  • Go का crypto/rand पैकेज ऐसे operating system interfaces के बीच के अंतर को abstract करता है और rand.Read नाम का एक समान interface देता है.

ChaCha8Rand generator

  • DJB के ChaCha stream cipher को modify करके बनाया गया नया generator.
  • यह 8-round version, यानी ChaCha8, का उपयोग करता है. यह ChaCha20 से 2.5 गुना तेज़ है और फिर भी सुरक्षित है.
  • 32-byte seed को ChaCha8 key के रूप में उपयोग किया जाता है. हर 16 blocks पर बने blocks के अंतिम 32 bytes को अगले 16 blocks की key के रूप में उपयोग किया जाता है, जिससे forward secrecy मिलती है.
  • math/rand/v2 का rand.Float64, rand.N आदि हमेशा इसी generator का उपयोग करते हैं.
  • math/rand भी इसी generator का उपयोग करता है. लेकिन rand.Seed कॉल होने पर यह Go 1 generator का उपयोग करता है.
  • Runtime भी नए map का hash seed चुनते समय ChaCha8Rand का उपयोग करता है.

सुरक्षा से जुड़ी गलतियों का समाधान

  • Go 1.22, math/rand को मज़बूत बनाकर, code बदले बिना भी program को अधिक सुरक्षित बनाता है.
  • उदाहरण के लिए, अगर math/rand के Read का गलत उपयोग करके key generation आदि में इस्तेमाल किया गया हो, तो Go 1.20 में यह गंभीर security problem है, लेकिन Go 1.22 में यह सिर्फ़ एक गलती भर रह जाती है.
  • UUID generation या frontend server के load balancing जैसे ऐसे उपयोगों में भी, जो देखने में "crypto" जैसे नहीं लगते, ChaCha8Rand इस्तेमाल करने पर यह Go 1 generator की तुलना में बहुत अधिक मज़बूत हो जाता है.

प्रदर्शन

  • ChaCha8Rand का performance, Go 1 generator या PCG के समान स्तर का है.
  • 32-bit code में, जहाँ PCG को 128-bit multiplication चाहिए, वहाँ ChaCha8Rand अधिक तेज़ है.
  • math/rand/v2 के उन algorithms की वजह से जो 64-bit division से बचते हैं, N(1000) operation में कभी-कभी ChaCha8Rand या PCG, Go 1 generator से भी तेज़ हो सकते हैं.
  • कुल मिलाकर ChaCha8Rand, Go 1 generator से धीमा है, लेकिन यह 2 गुना से अधिक धीमा नहीं होता, और सामान्य server पर अंतर 3ns से ज़्यादा नहीं होता.

GN⁺ की राय

  • Go 1.22 में ChaCha8Rand का अपनाया जाना ऐसा आदर्श language-level सुधार माना जा सकता है, जिसने security को काफ़ी बढ़ाया है और performance hit को न्यूनतम रखा है. यह विशेष रूप से प्रभावशाली है कि developers की आम गलतियों को language स्तर पर ही मूल रूप से रोका गया.
  • जैसा कि मुख्य लेख में भी कहा गया है, ऐसी गलती सिर्फ़ Go तक सीमित नहीं है, बल्कि दूसरी भाषाओं में भी आम है. System security को developer की गलती पर निर्भर नहीं होना चाहिए, इसलिए दूसरी भाषाओं को भी Go की तरह "mathematical" random number generation में cryptographically strong pseudorandom generator अपनाने की दिशा में बढ़ना चाहिए.
  • हालाँकि ChaCha8Rand, crypto_box या xchacha20poly1305 जैसे cryptographic primitives में उपयोग के लिए उपयुक्त नहीं है. ऐसे उपयोगों में अब भी crypto/rand का सीधे उपयोग करना चाहिए.
  • यह थोड़ा अप्रत्याशित लगा कि Go runtime ने map hash seed चुनने में भी ChaCha8Rand का उपयोग करना शुरू किया. Hash seed के लिए cryptographic randomness वास्तव में अनिवार्य है या नहीं, यह स्पष्ट नहीं है, लेकिन जटिल हमलों की संभावना को शुरू से ही बंद कर देने की development team की security mindset यहाँ उभरकर सामने आती है.
  • Language के default package math/rand की quality बेहतर हो जाने के बाद, आगे applications में सीधे math/rand का उपयोग अधिक होने की संभावना है. जिन projects ने अब तक math/rand की predictability के कारण अलग random generation library का उपयोग किया था, वे इस बदलाव का लाभ उठा सकते हैं.

1 टिप्पणियां

 
GN⁺ 2024-05-08
Hacker News की राय

संक्षेप में, बात यह है:

  • Go 1.20 में math/rand पैकेज का Read फ़ंक्शन deprecated होने के बाद, ऐसे मामले मिले जहाँ इसे गलती से crypto/rand की जगह इस्तेमाल किया गया। इससे सुरक्षा के लिहाज़ से कमज़ोर deterministic random number generator का उपयोग हो जाने की समस्या पैदा हुई।
  • सुरक्षा के लिए Go के डिफ़ॉल्ट random number generator को CSPRNG (cryptographically secure pseudorandom number generator) में बदलना बेहतर तरीका है। केवल वहीं स्पष्ट रूप से PRNG चुना जाना चाहिए जहाँ उसकी सच में ज़रूरत हो।
  • gosec और golangci-lint जैसे static analysis tools math/rand के उपयोग पर चेतावनी देते हैं।
  • math/rand/v2 पैकेज ChaCha8 cipher का उपयोग करता है और system entropy से seed किया जाता है, जिससे यह "सुरक्षित" लग सकता है, लेकिन फिर भी security-sensitive कामों के लिए उपयुक्त नहीं है। वहाँ crypto/rand का ही उपयोग होना चाहिए।
  • Go 1 का math/rand तकनीकी रूप से additive lagged Fibonacci generator माना जा सकता है।
  • नया math/rand सबसे खराब स्थिति में भी पुराने non-secure random generator की लगभग आधी गति देता है, और अधिकांश benchmarks में लगभग कोई अंतर नहीं दिखा। Go standard library में सुरक्षा और performance के बीच संतुलित समझौता कर रहा है।
  • इसे Java के java.util.Random जैसी गलतियों को रोकने वाले developer-friendly approach के रूप में देखा गया।
  • यह सवाल भी उठा कि ChaCha8 क्यों चुना गया, और AES-GCM जैसे hardware acceleration वाले block ciphers क्यों नहीं इस्तेमाल किए गए।