AES-GCM-HKDF स्ट्रीमिंग AEAD

यह दस्तावेज़ औपचारिक रूप से AES-GCM-HKDF स्ट्रीमिंग कुंजियों (type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey के तौर पर प्रोटो फ़ॉर्मैट में कोड में बदली गई) से दिखाए गए गणितीय फ़ंक्शन के बारे में बताता है.

एन्क्रिप्ट (सुरक्षित) करने का यह तरीका, [HRRV15]1 पर आधारित नहीं है. सुरक्षा का विश्लेषण करने के लिए, हम [HS20]2 को देखते हैं.

कुंजी और पैरामीटर

कुंजियों की जानकारी नीचे दिए गए हिस्सों में दी गई है (इस दस्तावेज़ में सभी साइज़ बाइट में हैं):

  • \(\mathrm{KeyValue}\), एक बाइट स्ट्रिंग.
  • \(\mathrm{CiphertextSegmentSize} \in \{1, 2, \ldots, 2^{31}-1\}\).
  • \(\mathrm{DerivedKeySize} \in \{16, 32\}\).
  • \(\mathrm{HkdfHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\).

सही कुंजियां, इन प्रॉपर्टी की ज़रूरी शर्तों को पूरा करती हैं:

  • \(\mathrm{len}(\mathrm{KeyValue}) \geq \mathrm{DerivedKeySize}\).
  • \(\mathrm{CiphertextSegmentSize} > \mathrm{DerivedKeySize} + 24\) (जैसा कि बाद में बताया गया है, \(\mathrm{len}(\mathrm{Header}) + 16\) यह इसके बराबर है).

इनमें से किसी भी प्रॉपर्टी का पालन नहीं करने वाली कुंजियां, Tink से अस्वीकार कर दी जाती हैं. ऐसा तब किया जाता है, जब कुंजी को पार्स किया जाता है या इससे जुड़ा प्रिमिटिव बनाया जाता है.

एन्क्रिप्ट (सुरक्षित) करने का फ़ंक्शन

मैसेज को \(\mathrm{Msg}\) उससे जुड़े डेटा के साथ एन्क्रिप्ट (सुरक्षित) करने के लिए\(\mathrm{AssociatedData}\), हम एक हेडर बनाते हैं, मैसेज को सेगमेंट में बांटते हैं, हर सेगमेंट को एन्क्रिप्ट करते हैं, और सेगमेंट को जोड़ते हैं. इन चरणों के बारे में नीचे बताया गया है.

हेडर बनाना

हेडर बनाने के लिए, हम पहले \(\mathrm{Salt}\) लंबाई \(\mathrm{DerivedKeySize}\)की एक रैंडम स्ट्रिंग चुनते हैं. इसके बाद, हम 7 लंबाई की \(\mathrm{NoncePrefix}\) एक रैंडम स्ट्रिंग चुनते हैं.

इसके बाद, हम \(\mathrm{Header} := \mathrm{len}(\mathrm{Header}) \| \mathrm{Salt} \| \mathrm{NoncePrefix}\)को सेट करते हैं, जहां हेडर की लंबाई को एक बाइट में एन्कोड किया जाता है. हम समझते हैं कि \(\mathrm{len}(\mathrm{Header}) \in \{24, 40\}\).

इसके बाद, हम आउटपुट लंबाई \(\mathrm{DerivedKeySize}\)के साथ \(\mathrm{HkdfHashType}\) और इनपुट \(\mathrm{ikm} := \mathrm{KeyValue}\), \(\mathrm{salt} := \mathrm{Salt}\), और \(\mathrm{info} := \mathrm{AssociatedData}\)से मिले हैश फ़ंक्शन के साथ HKDF3 का इस्तेमाल करते हैं. हम नतीजे को \(k\)कहते हैं.

मैसेज को अलग-अलग हिस्सों में बांटा जा रहा है

इसके बाद, मैसेज \(\mathrm{Msg}\) अलग-अलग हिस्सों में बंट जाएगा: \(\mathrm{Msg} = M_0 \| M_1 \| \cdots \| M_{n-1}\).

उनकी अवधि इस तरह चुनी जाती है कि वे इन शर्तों को पूरा कर सकें:

  • \(\mathrm{len}(M_0) \in \{0,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{len}(\mathrm{Header}) - \mathrm{16}\}\).
  • अगर \(n>1\), तो \(\mathrm{len}(M_1), \ldots, \mathrm{len}(M_{n-1}) \in \{1,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{16}\}\).
  • अगर \(n>1\), तो \(\mathrm{len}(M_{0}), \ldots, \mathrm{len}(M_{n-2})\) की लंबाई, ऊपर बताई गई कंस्ट्रेंट के मुताबिक ज़्यादा से ज़्यादा होनी चाहिए.

इस बंटवारे में, \(n\) ज़्यादा से ज़्यादा \(2^{32}\)हो सकता है. ऐसा न करने पर, एन्क्रिप्ट (सुरक्षित) नहीं किया जा सका.

ब्लॉक को एन्क्रिप्ट (सुरक्षित) करना

सेगमेंट को एन्क्रिप्ट (सुरक्षित) करने के लिए \(M_i\), हम सबसे पहले \(\mathrm{IV}_i := \mathrm{NoncePrefix} \| \mathrm{i} \| b\)को कंप्यूट करते हैं. इसमें हम बिग-एंडियन एन्कोडिंग का इस्तेमाल करके,\(\mathrm{i}\) 4 बाइट में कोड में बदलते हैं. अगर $i < n-1$ और 0x01 नहीं हैं, तो बाइट $b$ को 0x00 पर सेट करते हैं.

इसके बाद, हम \(M_i\) AES GCM4 का इस्तेमाल करके एन्क्रिप्ट (सुरक्षित) करते हैं. इसमें \(\mathrm{DerivedKey}\), इनिशलाइज़ेशन वेक्टर \(\mathrm{IV}_i\)होता है, और उससे जुड़ा डेटा \(A\) खाली स्ट्रिंग होती है. हमने \(C_i\) को एन्क्रिप्ट (सुरक्षित) करने के इस तरीके को लागू किया है (यानी, ऊपर दी गई जानकारी में \(C\) और \(T\) को जोड़ना).

सेगमेंट को जोड़ें

आखिर में, सभी सेगमेंट को\(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\)के तौर पर जोड़ा जाता है, जो कि फ़ाइनल सादे टेक्स्ट है.

डिक्रिप्शन

डिक्रिप्शन सिर्फ़ एन्क्रिप्शन को बदल देता है. हम हेडर का इस्तेमाल नॉन्स पाने के लिए करते हैं और साइफ़रटेक्स्ट के हर सेगमेंट को अलग-अलग डिक्रिप्ट करते हैं.

एपीआई, फ़ाइल के आखिर में जांच किए बिना ही रैंडम ऐक्सेस या फ़ाइल की शुरुआत में ऐक्सेस दे सकते हैं (और आम तौर पर ऐसा करते हैं). यह जान-बूझकर किया गया है, क्योंकि पिछले और बाकी बचे सभी साइफ़रटेक्स्ट ब्लॉक को डिक्रिप्ट किए बिना, \(M_i\) इन्हें \(C_i\)डिक्रिप्ट किया जा सकता है.

हालांकि, एपीआई को इस बात का ध्यान रखना चाहिए कि उपयोगकर्ता, फ़ाइल के एंड-एंड और डिक्रिप्शन की गड़बड़ी होने के बारे में गुमराह न हों. दोनों मामलों में, हो सकता है कि एपीआई को गड़बड़ी का जवाब देना पड़े. अंतर को अनदेखा करने से, कोई विरोधी फ़ाइल को सही तरीके से छोटा कर सकता है.

कुंजियों को सीरियल में बनाना और पार्स करना

कुंजी को "Tink Proto" फ़ॉर्मैट में क्रम से लगाने के लिए, हम सबसे पहले aes_gcm_hkdf_streaming.proto पर दिए गए प्रोटो में पैरामीटर को साफ़ तौर पर मैप करते हैं. version फ़ील्ड को 0 पर सेट करना ज़रूरी है. इसके बाद, हम सामान्य प्रोटो सीरियलाइज़ेशन का इस्तेमाल करके इसे क्रम से लगाते हैं और नतीजे वाली स्ट्रिंग को KeyData प्रोटो के फ़ील्ड की वैल्यू में एम्बेड करते हैं. हमने type_url फ़ील्ड को type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey पर सेट किया है. इसके बाद, हमने key_material_type को SYMMETRIC पर सेट करके इसे कीसेट में एम्बेड किया. आम तौर पर, हम output_prefix_type को RAW पर सेट करते हैं. इसका अपवाद यह है कि अगर कुंजी को output_prefix_type के लिए सेट की गई किसी दूसरी वैल्यू के साथ पार्स किया गया है, तो Tink में RAW या पिछली वैल्यू सेट हो सकती है.

किसी कुंजी को पार्स करने के लिए, हम ऊपर दी गई प्रक्रिया को उलट देते हैं (प्रोटो को पार्स करते समय सामान्य तरीके से). key_material_type फ़ील्ड को अनदेखा किया जाता है. output_prefix_type की वैल्यू को अनदेखा किया जा सकता है या RAW से output_prefix_type अलग वाली कुंजियों को अस्वीकार किया जा सकता है. जिन कुंजियों का version 0 से अलग है उन्हें अस्वीकार करना होगा.

आम तौर पर होने वाली समस्याएं

ऊपर बताए गए एन्क्रिप्शन फ़ंक्शन को लागू करना सुरक्षित नहीं है. फ़ोर्क सेफ़्टी देखें.

References


  1. [HRRV15] होआंग, रेहानिटाबार, रोगवे, विज़ार. ऑनलाइन प्रमाणित करने के तरीके को सुरक्षित करना और उसे दोबारा इस्तेमाल करने से रोकने में मदद मिलती है. क्रिप्टो करंसी 2015. https://eprint.iacr.org/2015/189 

  2. [HS20] Google की Tink लाइब्रेरी में स्ट्रीमिंग एन्क्रिप्शन की सुरक्षा. होआंग, शेन, 2020. https://eprint.iacr.org/2020/1019 

  3. [HKDF] एचएमएसी-आधारित एक्स्ट्रैक्ट-और-एक्सपैंड की डेरिवेशन फ़ंक्शन (HKDF), RFC 5869. https://www.rfc-editor.org/rfc/rfc5869 

  4. एनआईएसटी SP 800-38D, ऑपरेशन के ब्लॉक साइफ़र मोड के लिए सुझाव: गैलोइस/काउंटर मोड (GCM) और GMAC.