इस दस्तावेज़ में, एईएस-जीसीएम-एचकेडीएफ़ स्ट्रीमिंग पासकोड के ज़रिए दिखाए गए मैथमैटिकल फ़ंक्शन के बारे में आधिकारिक तौर पर बताया गया है. इन पासकोड को प्रोटो फ़ॉर्मैट में type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey
के तौर पर एन्कोड किया गया है.
यह एन्क्रिप्शन, HRRV151 पर आधारित है. सुरक्षा विश्लेषण के लिए, हम HS202 का रेफ़रंस देते हैं.
कुंजी और पैरामीटर
कुंजियों के बारे में इन हिस्सों से बताया जाता है (इस दस्तावेज़ में सभी साइज़, बाइट में दिए गए हैं):
- \(\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}\) और एक जैसी रैंडम स्ट्रिंग \(\mathrm{NoncePrefix}\)चुनते हैं, जिसकी लंबाई 7 है.
इसके बाद, हम \(\mathrm{Header} := \mathrm{len}(\mathrm{Header}) \| \mathrm{Salt} \| \mathrm{NoncePrefix}\)सेट करते हैं, जहां हेडर की लंबाई को एक बाइट के तौर पर एन्कोड किया जाता है. ध्यान दें कि \(\mathrm{len}(\mathrm{Header}) \in \{24, 40\}\).
इसके बाद, हम \(\mathrm{HkdfHashType}\)और इनपुट \(\mathrm{ikm} := \mathrm{KeyValue}\), \(\mathrm{salt} := \mathrm{Salt}\), और \(\mathrm{info} := \mathrm{AssociatedData}\)से दिए गए हैश फ़ंक्शन के साथ HKDF3 का इस्तेमाल करते हैं. साथ ही, आउटपुट की लंबाई \(\mathrm{DerivedKeySize}\)का इस्तेमाल करते हैं. हम नतीजे को \(\mathrm{DerivedKey}\)कहते हैं.
मैसेज को बांटना
इसके बाद, मैसेज \(\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}\) , बिग-इंडियन कोड में चार बाइट होता है और अगर $i < n-1$ है, तो बाइट $b$ 0x00
होता है. इसके अलावा, अगर $i < n-1$ नहीं है, तो बाइट $b$ 0x01
होता है.
इसके बाद, हम \(M_i\) एईएस-जीसीएम4 का इस्तेमाल करके एन्क्रिप्ट करते हैं.इसमें पासकोड\(\mathrm{DerivedKey}\), इनिशलाइज़ेशन वेक्टर \(\mathrm{IV}_i\), और उससे जुड़ा डेटा खाली स्ट्रिंग होता है. \(C_i\) , इस एन्क्रिप्शन का नतीजा है. इसका मतलब है कि लिंक किए गए एईएस-जीसीएम रेफ़रंस के सेक्शन 5.2.1.2 में, \(C\) और \(T\) को जोड़ना.
एन्क्रिप्ट किए गए सेगमेंट को जोड़ना
आखिर में, सभी सेगमेंट को \(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\)के तौर पर जोड़ दिया जाता है. यह फ़ाइनल सिफरटेक्स्ट होता है.
डिक्रिप्ट करना
डिक्रिप्ट करने की प्रोसेस में, एन्क्रिप्ट (सुरक्षित) किए गए डेटा को वापस उसके मूल रूप में लाया जाता है. हम हेडर का इस्तेमाल करके\(\mathrm{NoncePrefix}\)पाते हैं और सिफरटेक्स्ट के हर सेगमेंट को अलग-अलग डिक्रिप्ट करते हैं.
एपीआई, फ़ाइल के आखिर में मौजूद डेटा की जांच किए बिना, फ़ाइल के शुरू में मौजूद डेटा को ऐक्सेस कर सकते हैं. आम तौर पर, एपीआई ऐसा करते हैं. ऐसा जान-बूझकर किया जाता है, क्योंकि \(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 से अलग है उन्हें अस्वीकार कर दिया जाना चाहिए.
पहले से मालूम समस्याएं
ऊपर बताए गए एन्क्रिप्शन फ़ंक्शन को लागू करने पर, हो सकता है कि फ़ॉर्क करने से डेटा को खतरा हो. फ़ॉर्क की सुरक्षा देखें.
रेफ़रंस
-
Hoang, Reyhanitabar, Rogaway, Vizar, 2015. ऑनलाइन पुष्टि वाला एन्क्रिप्शन और नॉन्स का फिर से इस्तेमाल करने से जुड़ी गलत गतिविधियों से बचाव. CRYPTO 2015. https://eprint.iacr.org/2015/189 ↩
-
होआंग, शेन, 2020. Google की Tink लाइब्रेरी में स्ट्रीमिंग एन्क्रिप्शन की सुरक्षा. https://eprint.iacr.org/2020/1019 ↩
-
RFC 5869. एचएमएसी पर आधारित, पासकोड निकालने और उसे बड़ा करने वाला फ़ंक्शन (एचकेडीएफ़). https://www.rfc-editor.org/rfc/rfc5869 ↩
-
NIST SP 800-38D. ब्लॉक सिफर मोड के इस्तेमाल के लिए सुझाव: Galois/Counter Mode (GCM) और GMAC. https://csrc.nist.gov/pubs/sp/800/38/d/final ↩