AES-CTR HMAC স্ট্রিমিং AEAD

এই নথিটি আনুষ্ঠানিকভাবে AES-CTR HMAC স্ট্রিমিং কী দ্বারা উপস্থাপিত গাণিতিক ফাংশনকে সংজ্ঞায়িত করে (প্রোটো ফর্ম্যাটে type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey হিসাবে এনকোড করা হয়েছে)।

এই এনক্রিপশনটি ঢিলেঢালাভাবে [HRRV15] 1 এর উপর ভিত্তি করে। নিরাপত্তা বিশ্লেষণের জন্য আমরা [HS20] 2 উল্লেখ করি। এছাড়াও নোট করুন যে Tink ক্রস ল্যাঙ্গুয়েজ টেস্টে একটি পরীক্ষা আছে aes_ctr_hmac_streaming_key_test.py যাতে test_manually_created_test_vector থাকে এবং কিভাবে একটি সাইফারটেক্সট পেতে হয় তার সম্পূর্ণ ওয়াকথ্রু সহ।

কী এবং পরামিতি

কীগুলি নিম্নলিখিত অংশগুলি দ্বারা বর্ণনা করা হয়েছে (এই নথিতে সমস্ত আকার বাইটে রয়েছে):

  • \(\mathrm{InitialKeyMaterial}\), একটি বাইট স্ট্রিং: প্রাথমিক কী উপাদান।
  • \(\mathrm{CiphertextSegmentSize} \in \{1, 2, \ldots, 2^{31}-1\}\)।
  • \(\mathrm{DerivedKeySize} \in \{16, 32\}\)।
  • \(\mathrm{HkdfHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\)।
  • \(\mathrm{HmacHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\)।
  • \(\mathrm{HmacTagSize} \in \mathbb{N}\).

বৈধ কীগুলি অতিরিক্তভাবে নিম্নলিখিত বৈশিষ্ট্যগুলিকে সন্তুষ্ট করে:

  • \(\mathrm{len}(\mathrm{InitialKeyMaterial}) \geq \mathrm{DerivedKeySize}\)।
  • \(\mathrm{HmacHashType} = \mathrm{SHA1}\) হলে \(\mathrm{HmacTagSize} \in \{10, \ldots, 20\}\)।
  • \(\mathrm{HmacHashType} = \mathrm{SHA256}\) হলে \(\mathrm{HmacTagSize} \in \{10, \ldots, 32\}\)।
  • \(\mathrm{HmacHashType} = \mathrm{SHA512}\) হলে \(\mathrm{HmacTagSize} \in \{10, \ldots, 64\}\)।
  • \(\mathrm{CiphertextSegmentSize} > \mathrm{DerivedKeySize} + \mathrm{HmacTagSize} + 8\) (এটি\(\mathrm{len}(\mathrm{Header}) + \mathrm{HmacTagSize}\) এর সমান যা পরে ব্যাখ্যা করা হয়েছে)।

যে কীগুলি এই বৈশিষ্ট্যগুলির কোনওটিই সন্তুষ্ট করে না সেগুলি টিঙ্ক দ্বারা প্রত্যাখ্যান করা হয় (হয় যখন কীটি পার্স করা হয় বা যখন সংশ্লিষ্ট আদিম তৈরি করা হয়)৷

এনক্রিপশন ফাংশন

সম্পর্কিত ডেটা l10n\(\mathrm{AssociatedData}\)সহ একটি বার্তা \(\mathrm{Msg}\) এনক্রিপ্ট করতে, আমরা একটি শিরোনাম তৈরি করি, বার্তাটিকে সেগমেন্টে বিভক্ত করি, প্রতিটি সেগমেন্ট এনক্রিপ্ট করি এবং সেগমেন্টগুলিকে সংযুক্ত করি। আমরা নিম্নলিখিত এই পদক্ষেপগুলি ব্যাখ্যা করি।

হেডার তৈরি করা হচ্ছে

হেডার তৈরি করতে, আমরা প্রথমে \(\mathrm{Salt}\)\(\mathrm{DerivedKeySize}\)placeholder18 বাছাই করি। আমরা পরবর্তীতে 7 দৈর্ঘ্যের একটি অভিন্ন র্যান্ডম স্ট্রিং\(\mathrm{NoncePrefix}\) বেছে নিই।

তারপরে আমরা\(\mathrm{Header} := \mathrm{len}(\mathrm{Header}) \| \mathrm{Salt} \| \mathrm{NoncePrefix}\)সেট করি, যেখানে হেডারের দৈর্ঘ্য একক বাইট হিসাবে এনকোড করা হয়। আমরা লক্ষ করি যে\(\mathrm{len}(\mathrm{Header}) \in \{24, 40\}\)।

এর পরে, আমরা এই বার্তাটির জন্য l10n\(\mathrm{DerivedKeySize} + 32\) দৈর্ঘ্যের মূল উপাদান গণনা করতে হ্যাশ-ফাংশন \(\mathrm{HkdfHashType}\)সহ HKDF 3 ব্যবহার করি:\(k := \mathrm{HKDF}(\mathrm{InitialKeyMaterial}, \mathrm{Salt}, \mathrm{AssociatedData})\)। ইনপুটগুলি\(\mathrm{HKDF}\)এর সংশ্লিষ্ট ইনপুটগুলিতে ব্যবহৃত হয়: \(\mathrm{InitialKeyMaterial}\) হল \(\mathrm{ikm}\),\(\mathrm{Salt}\) হল সল্ট, এবং\(\mathrm{AssociatedData}\) হল \(\mathrm{info}\)হিসাবে।

স্ট্রিং \(k\) তারপর দুটি অংশে বিভক্ত হয় \(k_1 \| k_2 := k\), যেমন\(\mathrm{len}(k_1) = \mathrm{DerivedKeySize}\) এবং \(\mathrm{len}(k_2) = 32\)।

বার্তা বিভক্ত করা

\(M\) বার্তাটি পরবর্তী অংশে বিভক্ত: \(M = M_0 \| M_1 \| \cdots \| M_{n-1}\)।

তাদের দৈর্ঘ্য বেছে নেওয়া হয়েছে যাতে তারা সন্তুষ্ট হয়:

  • \(\mathrm{len}(M_0) \in \{0,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{len}(\mathrm{Header}) - \mathrm{HmacTagSize}\}\)।
  • যদি \(n > 1\), তাহলে \(\mathrm{len}(M_1), \ldots, \mathrm{len}(M_{n-1}) \in \{1,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{HmacTagSize}\}\)।
  • যদি \(n > 1\), তাহলে \(M_{0}, \ldots, M_{n-2}\) সীমাবদ্ধতার উপরোক্ত অনুযায়ী সর্বাধিক দৈর্ঘ্য থাকতে হবে।

এই বিভাজনে, \(n\) সর্বাধিক \(2^{32}\)হতে পারে। অন্যথায়, এনক্রিপশন ব্যর্থ হয়।

ব্লক এনক্রিপ্ট করা হচ্ছে

সেগমেন্ট \(M_i\)এনক্রিপ্ট করতে, আমরা প্রথমে\(\mathrm{IV}_i := \mathrm{NoncePrefix} \| \mathrm{i} \| b \| 0x00000000\)গণনা করি, যেখানে আমরা বিগ-এন্ডিয়ান এনকোডিং ব্যবহার করে 4 বাইটে \(\mathrm{i}\) এনকোড করি এবং $i < n-1$ এবং অন্যভাবে 0x01 হলে বাইট $b$ কে 0x00 সেট করি। .

আমরা তখন AES CTR কী \(M_i\) \(k_1\)এনক্রিপ্ট করি, এবং ইনিশিয়ালাইজেশন ভেক্টর\(\mathrm{IV}_i\)। অন্য কথায়, AES-এর আহ্বানের ইনপুটগুলি হল\(\mathrm{IV}_i, \mathrm{IV}_i + 1, \mathrm{IV}_i + 2, \ldots\)যেখানে \(\mathrm{IV}_i\) বড়-এন্ডিয়ান পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করা হয়। এটি \(C'_i\)প্রদান করে।

আমরা HMAC ব্যবহার করে ট্যাগ গণনা করি \(\mathrm{HmacHashType}\) দ্বারা প্রদত্ত হ্যাশ ফাংশন এবং\(\mathrm{IV}_i \| C'_i\)-placeholder56-এর উপর কী \(k_2\) দিয়ে।

তারপরে আমরা \(C_i\)পেতে ট্যাগের পরে সাইফারটেক্সট সংযুক্ত করি।

বিভাগগুলিকে সংযুক্ত করুন

অবশেষে, সমস্ত বিভাগগুলিকে\(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\)হিসাবে সংযুক্ত করা হয়েছে, যা চূড়ান্ত সাইফারটেক্সট।

ডিক্রিপশন ফাংশন

ডিক্রিপশন সহজভাবে এনক্রিপশনকে উল্টে দেয়। আমরা নন্স পেতে হেডার ব্যবহার করি এবং সাইফারটেক্সটের প্রতিটি সেগমেন্টকে পৃথকভাবে ডিক্রিপ্ট করি।

APIs (এবং সাধারণত করে) র্যান্ডম অ্যাক্সেস, বা ফাইলের শেষ পরিদর্শন ছাড়াই একটি ফাইলের শুরুতে অ্যাক্সেসের অনুমতি দিতে পারে। এটি ইচ্ছাকৃত, যেহেতু পূর্ববর্তী এবং অবশিষ্ট সাইফারটেক্সট ব্লকগুলিকে ডিক্রিপ্ট না করে \(C_i\)থেকে \(M_i\) ডিক্রিপ্ট করা সম্ভব।

যাইহোক, API-এর সতর্কতা অবলম্বন করা উচিত যাতে ব্যবহারকারীরা ফাইলের শেষ এবং ডিক্রিপশন ত্রুটিগুলিকে বিভ্রান্ত করতে না পারে: উভয় ক্ষেত্রেই API-কে সম্ভবত একটি ত্রুটি ফেরত দিতে হবে এবং পার্থক্য উপেক্ষা করার ফলে একটি প্রতিপক্ষকে কার্যকরভাবে ফাইল ছেঁটে ফেলতে সক্ষম হতে পারে।

ক্রমিককরণ এবং কীগুলির পার্সিং

"Tink Proto" ফরম্যাটে একটি কীকে সিরিয়ালাইজ করতে, আমরা প্রথমে aes_ctr_hmac_streaming.proto এ প্রদত্ত প্রোটোতে স্পষ্টভাবে প্যারামিটারগুলি ম্যাপ করি। ক্ষেত্র version 0 তে সেট করা দরকার। তারপরে আমরা এটিকে সাধারণ প্রোটো সিরিয়ালাইজেশন ব্যবহার করে সিরিয়ালাইজ করি এবং ফলাফল স্ট্রিংটিকে একটি কীডেটা প্রোটোর ক্ষেত্রের মানটিতে এম্বেড করি। আমরা type_url ক্ষেত্রটিকে type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey এ সেট করেছি। আমরা তখন 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 আছে এমন কীগুলি প্রত্যাখ্যান করা হবে।

তথ্যসূত্র


  1. [HRRV15] Hoang, Reyhanitabar, Rogaway, Vizar. অনলাইন প্রমাণীকৃত-এনক্রিপশন এবং এর অ-পুনঃব্যবহার অপব্যবহার-প্রতিরোধ। CRYPTO 2015। https://eprint.iacr.org/2015/189

  2. [HS20] গুগলের টিঙ্ক লাইব্রেরিতে স্ট্রিমিং এনক্রিপশনের নিরাপত্তা। হোয়াং, শেন, 2020। https://eprint.iacr.org/2020/1019

  3. [HKDF] HMAC-ভিত্তিক Extract-and-Expand Key Derivation Function (HKDF), RFC 5869. https://www.rfc-editor.org/rfc/rfc5869