ابتدایی ها و رابط ها
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
در مرحله بعد دو قطعه مهم از زبان مورد استفاده در Tink را تعریف می کنیم (به طور غیررسمی، اما سپس به طور رسمی)، یعنی Primitive و Interface .
بدوی
ابتدایی یک شی ریاضی است که مربوط به همه الگوریتم هایی است که برخی از کارها را به صورت ایمن انجام می دهند. برای مثال، الگوریتم اولیه AEAD شامل همه الگوریتمهای رمزگذاری است که ویژگیهای امنیتی مورد نیاز Tink از یک Aead را برآورده میکند.
ما تاکید می کنیم که اولیه ها به یک زبان برنامه نویسی یا روش خاصی برای دسترسی به آنها محدود نمی شوند. در عوض، باید به امر بدوی به عنوان یک شی کاملاً ریاضی فکر کرد. به عنوان مثال، اگر AEAD را در نظر بگیریم، اساساً از جفت توابع تشکیل می شود، یکی که رمزگذاری را انجام می دهد و دیگری که رمزگشایی را انجام می دهد.
رابط ها
رابط راهی است که در آن ما به کاربران دسترسی به یک اولیه را فراهم می کنیم. به عنوان مثال، ما انتظار داریم که در آینده Tink یک رابط Mac
و همچنین یک رابط StreamingMac
ارائه دهد که به شما امکان می دهد مک داده هایی را که مستقیماً در حافظه بارگذاری نمی شوند محاسبه کنید.
توجه داشته باشید که ما در اینجا به صراحت رابط ها و اولیه ها را تشخیص می دهیم. این باید روشن کند که شی ریاضی که این دو رابط به آن دسترسی می دهند یکسان هستند.
برای اکثر خوانندگان، توضیحات شهودی بالا احتمالا کافی است. با این وجود، ما احساس می کنیم که گاهی اوقات ارائه تعاریف رسمی از این مفاهیم می تواند مهم باشد.
توابع رمزنگاری
مفهوم تابع رمزنگاری به اندازه مفهوم اولیه مهم نیست، اما برای تعریف رسمی اولیه باید آن را معرفی کنیم.
- عملکرد رمزنگاری
یک تابع رمزنگاری یک نقشه است
\[ f: {\bf K} \times {\bf R} \times {\bf I} \to {\bf O}\]
از یک مجموعه \({\bf K}\) (فضای کلید)، یک مجموعه \({\bf R} = \{0,1\}^{\infty}\)(تصادفی، که ما آن را مجموعه ای از رشته های بیتی بی نهایت فرض می کنیم)، و یک مجموعه \({\bf I}\) (فضای ورودی)، به یک مجموعه \({\bf O}\) (فضای خروجی).
بعداً مشخص خواهد شد که چرا یک پارامتر تصادفی خاص را اضافه کرده ایم.
به عنوان مثال، یک امکان را نشان میدهیم که چگونه میتوان این مفاهیم را به AES-GCM نگاشت. برای هر اندازه کلید معتبر \(s_k\)، اندازه غیر عادی \(s_n\)، و اندازه برچسب\(s_t\)، AES-GCM از دو تابع رمزنگاری تشکیل شده است، یکی برای رمزگذاری و دیگری برای رمزگشایی. هر دو فضای کلید یکسانی خواهند داشت \({\bf
K} = \{0,1\}^{s_k}\).
برای تابع رمزگذاری \(\mathrm{Enc}\)، اولین \(s_n\) برای انتخاب nonce از بیت های تصادفی استفاده می شود.
اجازه دهید \({\bf B} = \{0,1\}^8\) یک بایت را نشان می دهد. فضای ورودی تابع رمزگذاری جفت است \({\bf I} = {\bf B}^{*}
\times {\bf B}^{*}\) جفت رشته بایت با طول دلخواه. اولین عنصر جفت پیام است، عنصر دوم داده های مرتبط است. استاندارد AES-GCM دارای محدودیت بالایی در طول ورودی ها است، اما ما ترجیح می دهیم طول های دلخواه را مجاز کنیم و در عوض یک نماد خطای ویژه اضافه کنیم. \(\bot\) به فضای خروجی سپس فضای خروجی تبدیل می شود \({\bf
O} = {\bf B}^* \cup \{\bot\}\)، جایی که ما به طور دلخواه نتیجه محاسبات موفق را به عنوان الحاق تعریف می کنیم \((\mathrm{IV} \|
\mathrm{ciphertext} \| \mathrm{tag})\) همانطور که در استاندارد و خروجی داده شده است\(\bot\)، در صورتی که برخی از ورودی ها بیش از حد طولانی باشد. از این رو، برای یک کلید ثابت، تابع رمزگذاری از نوع خود می شود \(\mathrm{Enc}_k : {\bf R} \times {\bf B}^*
\times {\bf B}^* \rightarrow {\bf B}^* \cup \{\bot\}\).
برای تابع رمزگشایی \(\mathrm{Dec}\) فضای کلید یکسان است. فضای ورودی به طور تصادفی یکسان است: \({\bf I} ={\bf B}^* \times {\bf B}^*\)، اما اکنون اولین عنصر خروجی تابع رمزگذاری است، در حالی که عنصر دوم هنوز داده های مرتبط است.
فضای خروجی نیز اتفاقاً یکسان است \({\bf O} = {\bf B}^* \cup
\{\bot\}\) (باز هم یک اتفاق). تفسیر تا حدودی متفاوت است، همانطور که \(\bot\) معمولاً یک خطای احراز هویت را نشان می دهد (اگرچه در صورتی که برخی از ورودی ها بیش از حد طولانی باشد، خروجی نیز خواهد بود).
ما تاکید می کنیم که رسمی سازی فوق تنها گزینه برای رسمی کردن استاندارد نیست . برای مثال، میتوان nonce را بخشی از ورودی در نظر گرفت، بهجای اینکه آن را از روی تصادفی بخوانیم (که منجر به یک بدوی بسیار متفاوت میشود). از طرف دیگر، میتوان خروجی را بهعنوان یک سهگانه حاوی nonce، متن رمزی و برچسب (بهجای الحاق) تعریف کرد. یا می توان فضای کلید را (تا حدودی خودسرانه) به آن محدود کرد\({\bf K} = \{0,1\}^{128} \cup \{0,1\}^{256}\).
- الگوریتم رمزنگاری:
یک الگوریتم رمزنگاری (متقارن) یک تاپل است
\[(f_1, ... f_k)\]
از توابع رمزنگاری، که در آن همه توابع فضای کلید یکسانی دارند. نوع الگوریتم رمزنگاری تاپل است \((({\bf I}_1, {\bf
O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\).
مثلا برای هر سه گانه معتبر \((s_k, s_n, s_t)\) اندازه کلید، nonce و برچسب، AES-GCM\({}_{s_k, s_n, s_t}\) یک الگوریتم رمزنگاری با دو تابع است \(\mathrm{Enc}\) و \(\mathrm{Dec}\) در بالا توضیح داده شد.
ابتدایی ها و رابط ها
در مرحله بعد یک رمزنگاری اولیه را تعریف می کنیم.
- بدوی
- بدوی مجموعه ای از الگوریتم های رمزنگاری است که در آن همه الگوریتم ها دارای یک نوع هستند. \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf
O}_k))\)، و فضاهای کلیدی الگوریتم ها به صورت جفتی جدا هستند.
به عنوان مثال، را در نظر بگیرید \(\mathrm{AEAD}\) ابتدایی در تینک این الگوریتمهای متعددی دارد، از جمله AES-GCM برای اندازههای کلید 128 و 256 بیت، با اندازه غیرنسی 96 بیت، AES-EAX با برخی از اندازههای کلید و XChaCha20Poly1305. آنها فضاهای کلیدی مجزا دارند، اما همه عملکردهای رمزنگاری یکسانی را ارائه می دهند\(\mathrm{Enc}\) و \(\mathrm{Dec}\). (ما در این بحث رسمی هدفی را در فروپاشی اندازه های کلیدی مختلف AES-GCM نمی بینیم، اما مطمئناً می توان چنین کرد).
تعریف اصول اولیه
روش معمول تفکر اولیه این است که ابتدا ویژگیهای توابع رمزنگاری را تعریف کنیم و سپس به سادگی آن را به عنوان همه این الگوریتمها در نظر بگیریم.
به عنوان مثال، برای AEAD ما می گوییم که \(\mathrm{Dec}_k(\mathrm{Enc}_k(m, a),
a) = m\) "همیشه" راضی است (مثلاً اگر متن ساده باشد \(m\) خیلی طولانی است). علاوه بر این، ما ویژگی های امنیتی داریم. برای مثال، برای یک کلید تصادفی، رمزگذاری از نظر معنایی امن است.
سپس AEAD اولیه مجموعه ای از تمام الگوریتم های رمزنگاری است که این ویژگی ها را برآورده می کند. به عبارت دیگر، در عمل وقتی یک ابتدایی خاص را تعریف می کنیم، آن را بر اساس ویژگی ها تعریف می کنیم. همانطور که تعریف نشان می دهد، ما لیستی از الگوریتم ها را ارائه نمی دهیم.
رابط ها
یک رابط در Tink دسترسی به یک اولیه را می دهد، به این معنا که امکان محاسبه عنصری از فضای خروجی را از فضای ورودی فراهم می کند. به عنوان مثال، رابط AEAD در جاوا را در نظر بگیرید:
public interface Aead {
byte[] encrypt(byte[] plaintext, byte[] associated_data) throws GeneralSecurityException;
byte[] decrypt(byte[] ciphertext, byte[] associated_data) throws GeneralSecurityException;
}
توجه داشته باشید که ما به تصادفی بودن دسترسی نمی دهیم. در عوض، ما به کاربر اجازه می دهیم تا عناصر فضای ورودی را فراهم کند. عدم اجازه دسترسی به تصادفی بودن البته عمدی است. 1
Tink گاهی اوقات چندین رابط برای یک اولیه ارائه می دهد. این می تواند بسیار مفید باشد، زیرا الزامات گاهی اوقات متفاوت است. با این حال، انجام این کار هزینه دارد: به طور کلی، هر چه رابط های بیشتری ارائه دهد، قابلیت همکاری کمتری دارد. به عنوان مثال، تصور کنید که شخصی کتابخانه ای را بر اساس Tink می نویسد که از کاربر می خواهد یک شی Aead
را ارسال کند (برای رمزگذاری داخلی چیزی). اگر تینک اینترفیس های بسیار متفاوتی را به آن ارائه دهد \(\mathrm{AEAD}\) بدوی، احتمال اینکه کاربر نمونه ای آماده نداشته باشد که برای کلیدی که کاربر انتخاب کرده و کتابخانه به طور همزمان کار کند زیاد است. از این رو، افزودن اینترفیس های بیشتر یک معامله است.
جز در مواردی که غیر از این ذکر شده باشد،محتوای این صفحه تحت مجوز Creative Commons Attribution 4.0 License است. نمونه کدها نیز دارای مجوز Apache 2.0 License است. برای اطلاع از جزئیات، به خطمشیهای سایت Google Developers مراجعه کنید. جاوا علامت تجاری ثبتشده Oracle و/یا شرکتهای وابسته به آن است.
تاریخ آخرین بهروزرسانی 2025-07-25 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-25 بهوقت ساعت هماهنگ جهانی."],[[["\u003cp\u003eTink uses Primitives, which are mathematical representations of secure algorithms, and Interfaces, which provide user access to these Primitives.\u003c/p\u003e\n"],["\u003cp\u003ePrimitives are defined by the security properties they satisfy, for example, AEAD requires semantic security and correct decryption.\u003c/p\u003e\n"],["\u003cp\u003eInterfaces in Tink provide controlled access to Primitives, often abstracting away internal details like randomness generation for security reasons.\u003c/p\u003e\n"],["\u003cp\u003eOffering multiple Interfaces for the same Primitive can improve flexibility but may reduce interoperability between different Tink users or libraries.\u003c/p\u003e\n"],["\u003cp\u003eWhile Primitives are abstract and language-independent, Interfaces are specific to a programming language and provide a way for users to interact with the underlying algorithms.\u003c/p\u003e\n"]]],["Tink defines *Primitives* as mathematical objects representing secure algorithms, like AEAD, which consists of encryption/decryption functions. *Interfaces* are the means to access these primitives. A *Cryptographic Function* maps keys, randomness, and input to output. A *Cryptographic Algorithm* is a tuple of such functions with the same key space. A *Primitive* is a set of Cryptographic Algorithms that have the same type and disjoint key spaces. Interfaces grant users access to the primitive's output, without providing access to randomness.\n"],null,["# Primitives and Interfaces\n\nWe next define (informally, but then more formally), two important pieces of\nthe language used in Tink, the *Primitive* and the *Interface*.\n\nPrimitive\n---------\n\nA primitive is a *mathematical* object corresponding to all algorithms\nperforming some task securely. For example, the AEAD primitive consists of all\nencryption algorithms which satisfy [the security properties which Tink requires\nof an Aead](https://developers.google.com/tink/aead#minimal_security_guarantees).\n\nWe stress that primitives are not bound to a programming language, or a specific\nway of\naccessing them. Instead, one should think of the primitive as the purely\nmathematical object. For example, if we consider AEAD, fundamentally it will\nconsist of pairs of functions, one which performs encryption, and one which\nperforms decryption.\n\nInterfaces\n----------\n\nAn interface is a way in which we provide users access to a primitive.\nFor example, we expect that in the future Tink will provides a `Mac` interface,\nbut also a `StreamingMac` interface, which allows to compute the mac of\ndata which is not directly loaded into memory.\n\nNote that we explicitly distinguish interfaces and primitives here. This should\nmake clear that the mathematical object to which these two interfaces give\naccess are the same.\n\nFormal definitions\n------------------\n\nFor most readers, the above intuitive explanations are probably enough.\nNevertheless, we feel that it can be important sometimes to provide formal\ndefinitions of these concepts.\n\n### Cryptographic functions\n\nThe concept of a cryptographic function is not as important as the concept of a\nprimitive, but we need to introduce it to formally define primitive.\n\nCryptographic Function\n\n: A *cryptographic function* is a map\n\n \\\\\\[ f: {\\\\bf K} \\\\times {\\\\bf R} \\\\times {\\\\bf I} \\\\to {\\\\bf O}\\\\\\]\n\n from a set \\\\({\\\\bf K}\\\\) (the key space), a set \\\\({\\\\bf R} = \\\\{0,1\\\\}\\^{\\\\infty}\\\\)\n (randomness, which we assume to be the set of infinite bitstrings), and a\n set \\\\({\\\\bf I}\\\\) (the input space), to a set \\\\({\\\\bf O}\\\\) (the output space).\n\nIt will become clear later why we added a specific randomness parameter.\n\nAs an example, we show one possibility how these concepts can be mapped to\nAES-GCM. For each valid key size \\\\(s_k\\\\), nonce size \\\\(s_n\\\\), and tag size\n\\\\(s_t\\\\), AES-GCM consists of two cryptographic functions, one for\nencryption, and one for decryption. Both will have the same key space \\\\({\\\\bf\nK} = \\\\{0,1\\\\}\\^{s_k}\\\\).\n\nFor the encryption function \\\\(\\\\mathrm{Enc}\\\\), the first \\\\(s_n\\\\) bits of\nrandomness will be used to select the nonce.\n\nLet \\\\({\\\\bf B} = \\\\{0,1\\\\}\\^8\\\\) denote a byte.\nThe input space of the encryption function is the pairs \\\\({\\\\bf I} = {\\\\bf B}\\^{\\*}\n\\\\times {\\\\bf B}\\^{\\*}\\\\) of pairs of byte strings of arbitrary length.\nThe first element of the pair is meant to be the message, the second element is\nthe associated data. The AES-GCM standard has an upper limit on the lengths of\nthe inputs, but we prefer to allow arbitrary lengths, and instead add a special\nerror symbol \\\\(\\\\bot\\\\) to the output space. The output space then becomes \\\\({\\\\bf\nO} = {\\\\bf B}\\^\\* \\\\cup \\\\{\\\\bot\\\\}\\\\), where we arbitrarily define the result of\nsuccessful computations as the concatenation \\\\((\\\\mathrm{IV} \\\\\\|\n\\\\mathrm{ciphertext} \\\\\\| \\\\mathrm{tag})\\\\) as given in the standard, and output\n\\\\(\\\\bot\\\\), in case some input is too long. Hence, for a fixed key, the\nencryption function becomes of type \\\\(\\\\mathrm{Enc}_k : {\\\\bf R} \\\\times {\\\\bf B}\\^\\*\n\\\\times {\\\\bf B}\\^\\* \\\\rightarrow {\\\\bf B}\\^\\* \\\\cup \\\\{\\\\bot\\\\}\\\\).\n\nFor the decryption function \\\\(\\\\mathrm{Dec}\\\\) the key space is the same. The\ninput space coincidentally is the same: \\\\({\\\\bf I} ={\\\\bf B}\\^\\* \\\\times {\\\\bf B}\\^\\*\\\\),\nbut now the first element is meant to be the output of the encryption function,\nwhile the second one is still the associated data.\n\nThe output space also happens to be the same \\\\({\\\\bf O} = {\\\\bf B}\\^\\* \\\\cup\n\\\\{\\\\bot\\\\}\\\\) (again a coincidence). The interpretation is somewhat different,\nas \\\\(\\\\bot\\\\) usually denotes an authentication error (though it will also be the\noutput in case some input is too long).\n\nWe stress that the above formalization is *not* the only option to formalize the\nstandard. For example, one could consider the nonce a part of the input, instead\nof reading it from the randomness (which results in a very different primitive).\nAlternatively, one could define the output as a triple containing the nonce,\nthe ciphertext, and the tag (instead of the concatenation). Or one could\nrestrict the key space (somewhat arbitrarily) to\n\\\\({\\\\bf K} = \\\\{0,1\\\\}\\^{128} \\\\cup \\\\{0,1\\\\}\\^{256}\\\\).\n\nCryptographic Algorithm:\n\n: A (symmetric) *cryptographic algorithm* is a tuple\n\n \\\\\\[(f_1, ... f_k)\\\\\\]\n\n of cryptographic functions, where all functions have the same key space. The\n *type* of the cryptographic algorithm is the tuple \\\\((({\\\\bf I}_1, {\\\\bf\n O}_1), \\\\ldots, ({\\\\bf I}_k, {\\\\bf O}_k))\\\\).\n\nFor example, for each valid triple \\\\((s_k, s_n, s_t)\\\\) of key, nonce, and tag\nsize, AES-GCM\\\\({}_{s_k, s_n, s_t}\\\\) is a cryptographic algorithm with the\ntwo functions \\\\(\\\\mathrm{Enc}\\\\) and \\\\(\\\\mathrm{Dec}\\\\) described above.\n\n### Primitives and interfaces\n\nWe next define a cryptographic primitive.\n\nPrimitive\n: A *primitive* is a set of cryptographic algorithms, where all the algorithms\n have the same type \\\\((({\\\\bf I}_1, {\\\\bf O}_1), \\\\ldots, ({\\\\bf I}_k, {\\\\bf\n O}_k))\\\\), and the key spaces of the algorithms are pairwise disjoint.\n\nAs an example, consider the \\\\(\\\\mathrm{AEAD}\\\\) primitive in Tink. It has multiple\nalgorithms, among those are AES-GCM for key sizes 128 and 256 bits, with nonce\nsize 96 bits, AES-EAX with some key sizes, and XChaCha20Poly1305. They have\ndisjoint key spaces, but all provide the same cryptographic functions\n\\\\(\\\\mathrm{Enc}\\\\) and \\\\(\\\\mathrm{Dec}\\\\). (We do not see a purpose in somehow\ncollapsing different key sizes of AES-GCM in this formal discussion, but of\ncourse one could do so).\n\n#### Defining primitives\n\nThe usual way of thinking of primitives is to first define properties of the\ncryptographic functions, and then simply considering the primitive to be all\nsuch algorithms.\n\nFor example, for AEAD we would say that \\\\(\\\\mathrm{Dec}_k(\\\\mathrm{Enc}_k(m, a),\na) = m\\\\) is 'always' satisfied (except e.g. if the plaintext \\\\(m\\\\) is too\nlong). In addition, we have security properties; for example, for\na random key, the encryption is semantially secure.\n\nThe AEAD primitive is then simply the set of all cryptographic algorithms which\nsatisfy these properties. In other words, in practice, when we define a specific\nprimitive, we define it based on properties. We do not give a list of\nalgorithms, as the definition suggests.\n\n#### Interfaces\n\nAn *interface* in Tink gives access to a primitive, in the sense that it allows\nto compute an element of the output space from the input space. For example,\nconsider the AEAD interface in Java: \n\n public interface Aead {\n byte[] encrypt(byte[] plaintext, byte[] associated_data) throws GeneralSecurityException;\n byte[] decrypt(byte[] ciphertext, byte[] associated_data) throws GeneralSecurityException;\n }\n\nNote that we do not give access to the randomness. Instead, we allow the user to\nprovide elements of the input space. Disallowing access to the randomness is of\ncourse on purpose.^[1](#fn1)^\n\nTink sometimes offers multiple interfaces for a single primitive.\nThis can be very useful, as requirements sometimes differ. Still, doing this\ncomes at a price: in general, the more interfaces one offers, the lower\ninteroperability is. For example, imagine\nthat someone writes a library based on Tink that requires the user to pass in an\n`Aead` object (to encrypt something internally). If Tink offers too many\ndifferent interfaces to the \\\\(\\\\mathrm{AEAD}\\\\) primitive, chances are high\nthat the user\ndoes not have an instance ready which works for the key the user picked and the\nlibrary at the same time. Hence, adding more interfaces is a trade-off. \n\n*** ** * ** ***\n\n1. AEAD ciphers have the property that they are secure\n against chosen ciphertext attacks, which is guaranteed only if there is no\n reuse of the nonce. The Aead interface in Tink is designed such that it\n prevents nonce reuse: the user cannot provide a nonce as input for encryption,\n instead, a new nonce is randomly generated for each encrypt operation. [↩](#fnref1)"]]