এই দস্তাবেজটি আনুষ্ঠানিকভাবে 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\) যেমনটি পরে ব্যাখ্যা করা হয়েছে)।
যে কীগুলি এই বৈশিষ্ট্যগুলির কোনওটিই সন্তুষ্ট করে না সেগুলি টিঙ্ক দ্বারা প্রত্যাখ্যান করা হয়, হয় যখন কীটি পার্স করা হয় বা যখন সংশ্লিষ্ট আদিম তৈরি করা হয়।
এনক্রিপশন ফাংশন
একটি বার্তা এনক্রিপ্ট করতে \(\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\}\).
এর পরে, আমরা প্রদত্ত হ্যাশ ফাংশন সহ HKDF 3 ব্যবহার করি \(\mathrm{HkdfHashType}\)এবং ইনপুট \(\mathrm{ikm} := \mathrm{KeyValue}\), \(\mathrm{salt} := \mathrm{Salt}\), এবং \(\mathrm{info} := \mathrm{AssociatedData}\), আউটপুট দৈর্ঘ্য সহ \(\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}\) বিগ-এন্ডিয়ান এনকোডিং-এ 4 বাইট এবং $i < n-1$ এবং অন্যথায় 0x01
হলে $b$ হল 0x00
।
তারপর আমরা এনক্রিপ্ট করি \(M_i\) AES-GCM 4 ব্যবহার করে, যেখানে কী আছে\(\mathrm{DerivedKey}\), আরম্ভ ভেক্টর হয় \(\mathrm{IV}_i\), এবং সংশ্লিষ্ট ডেটা হল খালি স্ট্রিং। \(C_i\) এই এনক্রিপশনের ফলাফল (অর্থাৎ এর সংমিশ্রণ \(C\) এবং \(T\) সংযুক্ত AES-GCM রেফারেন্সের অধ্যায় 5.2.1.2)।
এনক্রিপ্ট করা অংশগুলিকে সংযুক্ত করুন
পরিশেষে, সমস্ত বিভাগ হিসাবে একত্রিত হয় \(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\), যা চূড়ান্ত সাইফারটেক্সট।
ডিক্রিপশন
ডিক্রিপশন এনক্রিপশনকে উল্টে দেয়। আমরা প্রাপ্ত করার জন্য হেডার ব্যবহার করি\(\mathrm{NoncePrefix}\), এবং সাইফারটেক্সটের প্রতিটি সেগমেন্টকে পৃথকভাবে ডিক্রিপ্ট করুন।
APIs (এবং সাধারণত করে) র্যান্ডম অ্যাক্সেস, বা ফাইলের শেষ পরিদর্শন ছাড়াই একটি ফাইলের শুরুতে অ্যাক্সেসের অনুমতি দিতে পারে। এটি ইচ্ছাকৃত, যেহেতু এটি ডিক্রিপ্ট করা সম্ভব \(M_i\) থেকে \(C_i\), সমস্ত পূর্ববর্তী এবং অবশিষ্ট সাইফারটেক্সট ব্লকগুলি ডিক্রিপ্ট না করে।
যাইহোক, API-এর সতর্কতা অবলম্বন করা উচিত যাতে ব্যবহারকারীরা ফাইলের শেষ এবং ডিক্রিপশন ত্রুটিগুলিকে বিভ্রান্ত করতে না পারে: উভয় ক্ষেত্রেই API-কে সম্ভবত একটি ত্রুটি ফেরত দিতে হবে এবং পার্থক্য উপেক্ষা করার ফলে একটি প্রতিপক্ষকে কার্যকরভাবে ফাইল ছেঁটে ফেলতে সক্ষম হতে পারে।
ক্রমিককরণ এবং কীগুলির পার্সিং
"Tink Proto" ফরম্যাটে একটি কীকে সিরিয়ালাইজ করতে, আমরা প্রথমে aes_gcm_hkdf_streaming.proto এ প্রদত্ত প্রোটোতে স্পষ্টভাবে প্যারামিটারগুলি ম্যাপ করি। ক্ষেত্র version
0 তে সেট করা দরকার। তারপরে আমরা এটিকে সাধারণ প্রোটো সিরিয়ালাইজেশন ব্যবহার করে সিরিয়ালাইজ করি এবং ফলাফল স্ট্রিংটিকে একটি কীডেটা প্রোটোর ক্ষেত্রের মানটিতে এম্বেড করি। আমরা 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
আছে এমন কীগুলি প্রত্যাখ্যান করা যেতে পারে। 0 থেকে ভিন্ন version
আছে এমন কীগুলি অবশ্যই প্রত্যাখ্যান করতে হবে।
পরিচিত সমস্যা
উপরোক্ত এনক্রিপশন ফাংশনের বাস্তবায়ন কাঁটা নিরাপদ হবে বলে আশা করা যায় না। ফর্ক নিরাপত্তা দেখুন।
তথ্যসূত্র
Hoang, Reyhanitabar, Rogaway, Vizar, 2015। অনলাইন প্রমাণীকৃত-এনক্রিপশন এবং এর অ-পুনঃব্যবহার অপব্যবহার-প্রতিরোধ। CRYPTO 2015। https://eprint.iacr.org/2015/189 ↩
Hoang, Shen, 2020. Google-এর Tink লাইব্রেরিতে স্ট্রিমিং এনক্রিপশনের নিরাপত্তা। https://eprint.iacr.org/2020/1019 ↩
RFC 5869. HMAC-ভিত্তিক Extract-and-expand Key Derivation Function (HKDF)। https://www.rfc-editor.org/rfc/rfc5869 ↩
NIST SP 800-38D. অপারেশনের ব্লক সাইফার মোডের জন্য সুপারিশ: গ্যালোইস/কাউন্টার মোড (GCM) এবং GMAC। https://csrc.nist.gov/pubs/sp/800/38/d/final ↩