टिंक वायर का फ़ॉर्मैट

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

कीसेट को क्रम से लगाने की सुविधा

Tink, अपने कीसेट को सीरियलाइज़ करने के लिए Google protobuf का इस्तेमाल करता है.

  • बाइनरी सीरियलाइज़्ड कीसेट, सीरियलाइज़्ड Keyset proto होता है. इसे tink.proto में तय किया गया है. किसी कुंजी की KeyData वैल्यू प्रॉपर्टी, उससे जुड़े कुंजी टाइप का क्रम से लगाया गया प्रोटो होता है.
  • JSON में क्रम से लगाया गया कीसेट, JSON फ़ॉर्मैट में क्रम से लगाया गया Keyset proto होता है. ध्यान दें कि KeyData वैल्यू अब भी बाइनरी सीरियलाइज़ किया गया प्रोटो है.
  • एन्क्रिप्ट किया गया कीसेट, tink.proto में तय किया गया, क्रम से लगाया गया EncryptedKeyset प्रोटो होता है. इसमें एन्क्रिप्ट (सुरक्षित) किया गया बाइनरी सीरियलाइज़्ड कीसेट होता है. साथ ही, इसमें KeysetInfo का कुछ ऐसा मेटाडेटा भी हो सकता है जिसे एन्क्रिप्ट (सुरक्षित) नहीं किया गया है.

Tink का आउटपुट प्रीफ़िक्स

Tink की ज़्यादातर प्रिमिटिव, पांच बाइट के आउटपुट प्रीफ़िक्स के साथ काम करती हैं. इसमें ये शामिल हैं:

  • एक बाइट वाला वर्शन: 0x01
  • कुंजी का 4 बाइट का हिंट: यह इस्तेमाल की गई कुंजी का आईडी है.

कुछ लेगसी कुंजियां भी वर्शन बाइट 0x00 के साथ काम कर सकती हैं.

Prehash प्रिमिटिव, वर्शन बाइट 0xff का इस्तेमाल करता है. External Mu ML-DSA prehash values देखें.

ध्यान दें कि इन प्रीफ़िक्स की पुष्टि नहीं की जाती है. इसलिए, सुरक्षा के लिहाज़ से इन पर भरोसा नहीं किया जा सकता. Tink इनका इस्तेमाल, डिक्रिप्ट करने या पुष्टि करने की प्रोसेस को तेज़ करने के लिए करता है. इसके अलावा, इनका इस्तेमाल साइन प्रीहैश के मामले में हस्ताक्षर करने वाले की कुंजी चुनने के लिए भी किया जाता है.

AEAD

आम तौर पर, Tink, AEAD सिफ़रटेक्स्ट को इस तरह फ़ॉर्मैट करता है:

prefix || IV || ciphertext || tag

जब तक कि संबंधित आरएफ़सी में अलग से न बताया गया हो. prefix खाली होता है या यह 5 बाइट का Tink आउटपुट प्रीफ़िक्स होता है.

AES-CTR-HMAC

AES-CTR-HMAC के लिए, Tink, इससे जुड़े डेटा (एडी) के साथ एमएसी की गिनती इस तरह करता है:

AD || IV || ciphertext || bitlen(AD)

यहां bitlen(AD), एडी की लंबाई को बिट में दिखाता है. इसे 64-बिट बिग-एंडियन अनसाइंड इंटिजर के तौर पर दिखाया जाता है. यह एचएमएसी स्कीम, Mcgrew के AES-CBC-HMAC के ड्राफ़्ट के मुताबिक है.

डिटरमिनिस्टिक एईएडी

Tink, AES-SIV के लिए RFC 5297 लागू करता है. इससे सिंथेटिक इनिशलाइज़ेशन वेक्टर (एसआईवी) को एन्क्रिप्ट (सुरक्षित) किए गए टेक्स्ट की शुरुआत में रखा जाता है. प्रिमिटिव, Tink के आउटपुट में 5 बाइट का प्रीफ़िक्स जोड़ सकता है.

RFC 5297 में, एक से ज़्यादा डेटा को शामिल किया जा सकता है. हालांकि, Tink में सिर्फ़ एक डेटा को शामिल किया जा सकता है. यह RFC 5297 में मौजूद एक एलिमेंट वाली लिस्ट के बराबर होता है. जुड़ा हुआ खाली डेटा, एक ऐसी सूची होती है जिसमें एक खाली एलिमेंट होता है. यह एक खाली सूची नहीं होती.

स्ट्रीमिंग एईएडी

AES-CTR HMAC और AES-GCM-HKDF देखें.

एन्वेलप एन्क्रिप्शन

एनवेलप एन्क्रिप्शन, डेटा को डेटा एन्क्रिप्शन की DEK की मदद से एन्क्रिप्ट यानी सुरक्षित करता है. इसके लिए, Tink के एईएडी प्रिमिटिव का इस्तेमाल किया जाता है. एन्क्रिप्शन इस तरह काम करता है:

  • दिए गए कुंजी टेंप्लेट (या कुंजी पैरामीटर) का इस्तेमाल करके, एक नई DEK जनरेट की जाती है.
  • DEK को बाइट स्ट्रिंग में क्रम से लगाया जाता है. यह कुंजी टाइप प्रोटो के प्रोटोकॉल बफ़र सीरियलाइज़ेशन का सीरियलाइज़ेशन फ़ॉर्मैट है. उदाहरण के लिए, यह एईएस जीसीएम टाइप की कुंजी के डीईके के लिए, aes_gcm.proto में तय किया गया, क्रम से लगाया गया AesGcmKey प्रोटोकॉल बफ़र मैसेज है. प्रोटोकॉल बफ़र को क्रम से लगाने का तरीका जानने के लिए, प्रोटोकॉल बफ़र सीरियलाइज़ेशन देखें.
  • सीरियल किए गए DEK को बाहरी प्रोवाइडर (उदाहरण के लिए, GCP) की मदद से encrypted DEK में एन्क्रिप्ट (सुरक्षित) किया जाता है.
  • DEK का इस्तेमाल, सादे टेक्स्ट और उससे जुड़े डेटा को ciphertext में एन्क्रिप्ट करने के लिए किया जाता है. इसलिए, ciphertext का फ़ॉर्मैट, DEK से जुड़े एईएडी प्रिमिटिव के फ़ॉर्मैट जैसा ही होता है.

एन्वेलप एन्क्रिप्शन का आउटपुट फ़ॉर्मैट इस तरह होता है:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length 4 बाइट का होता है. इसमें encrypted DEK की लंबाई को 32-बिट के बिग-एंडियन पूर्णांक के तौर पर सेव किया जाता है.

MAC

Tink, इससे जुड़े आरएफ़सी का पालन करता है. प्रिमिटिव, टैग में 5 बाइट का Tink आउटपुट प्रीफ़िक्स जोड़ सकते हैं.

PRF सेट

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

हाइब्रिड एन्क्रिप्शन

Tink के हाइब्रिड एन्क्रिप्शन के लिए, वायर फ़ॉर्मैट इस तरह होता है:

prefix || encapsulated_key || encrypted_data

prefix फ़ील्ड की वैल्यू खाली है या यह Tink के आउटपुट प्रीफ़िक्स के तौर पर इस्तेमाल किया गया 5 बाइट का डेटा है. हर कुंजी टाइप में यह जानकारी होती है कि कितने बाइट पार्स करने हैं और encapsulated_key से उन बाइट को कैसे पार्स करना है.

एचपीकेई (हाइब्रिड पब्लिक की एन्क्रिप्शन)

Tink, RFC 9180 में बताए गए एचपीकेई स्टैंडर्ड का पालन करता है. एचपीकेई सिफ़रसुइट में ये तीन प्रिमिटिव शामिल होते हैं.

  • की एनकैप्सुलेशन मैकेनिज़्म (केईएम)
  • की डेरिवेशन फ़ंक्शन (केडीएफ़)
  • एसोसिएटेड डेटा के साथ पुष्टि किया गया एन्क्रिप्शन (एईएडी)

एचपीकेई स्टैंडर्ड, आरएफ़सी 9180, सेक्शन 10 में सामान्य वायर फ़ॉर्मैट के बारे में नहीं बताता है. Tink, एचपीकेई को लागू करने के लिए इन encapsulated_key और encrypted_data वैल्यू का इस्तेमाल करता है.

  • encapsulated_key
    • भेजने वाले की क्रम से लगाई गई सार्वजनिक पासकोड
    • आरएफ़सी 9180, सेक्शन 4.1 में इसे enc के तौर पर तय किया गया है
    • इस्तेमाल किए गए खास एचपीकेई केईएम के हिसाब से फ़ॉर्मैट तय किया जाता है
  • encrypted_data
    • साइफ़रटेक्स्ट और टैग (यानी, ciphertext || tag बिना आईवी के)
    • आरएफ़सी 9180, सेक्शन 4 में इसे ct के तौर पर तय किया गया है
    • फ़ॉर्मैट, इस्तेमाल किए गए खास एचपीकेई एईएडी के हिसाब से तय होता है
X25519 डिफ़ी-हेलमैन पर आधारित KEM

X25519 DHKEM के लिए, वैल्यू enc भेजने वाले की 32-बाइट डिफ़ी-हेलमैन सार्वजनिक कुंजी होती है.

ECIES-AEAD-HKDF

Tink के ECIES-AEAD-HKDF को लागू करने के लिए, encapsulated_key, Key Encapsulation Mechanism (KEM) का आउटपुट है और encrypted_data, Data Encapsulation Mechanism (DEM) का आउटपुट है.

KEM

कुंजी के टाइप के आधार पर, Tink कंप्रेस किए गए और कंप्रेस न किए गए एलिप्टिक कर्व पॉइंट का इस्तेमाल करता है. यह RFC 8422/ANSI.X9-62.2005 एन्कोडिंग स्टैंडर्ड का पालन करता है. बिना कंप्रेस किए गए पॉइंट के लिए, बाइट 0x04 के बाद x और y कोऑर्डिनेट, तय साइज़ वाले पूर्णांक के तौर पर होते हैं. कंप्रेस किए गए कोऑर्डिनेट के लिए, 0x02 या 0x03 बाइट और x कोऑर्डिनेट का इस्तेमाल किया जाता है. यह एक तय साइज़ वाला पूर्णांक होता है. X25519 के लिए, RFC 7748 की परिभाषा का इस्तेमाल किया जाता है (x कोऑर्डिनेट, तय साइज़ वाला पूर्णांक होता है).

DEM

encrypted_data के लिए, Tink वही फ़ॉर्मैट इस्तेमाल करता है जो AEAD के लिए इस्तेमाल किया जाता है. इसमें IV तय करना भी शामिल है.

कुंजी का अनुमान लगाना

सबसे पहले, शेयर किए गए पॉइंट का x कोऑर्डिनेट x_ss कैलकुलेट किया जाता है. इसके बाद, AEAD के लिए कुंजी को इस पर सेट किया जाता है:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

यहां encapsulated_key, बाइट के तौर पर पूरा KEM आउटपुट है.

डिजिटल हस्ताक्षर

Tink, इससे जुड़े आरएफ़सी का पालन करता है. प्रिमिटिव, जनरेट किए गए टैग में पांच बाइट का Tink आउटपुट प्रीफ़िक्स जोड़ सकते हैं.

ECDSA

कुंजी में मौजूद EcdsaSignatureEncoding फ़ील्ड के आधार पर, ECDSA हस्ताक्षर का फ़ॉर्मैट IEEE P1363 या ASN.1 DER होता है.

IEEE P1363 सिग्नेचर का फ़ॉर्मैट r || s होता है. इसमें r और s में शून्य जोड़े जाते हैं. साथ ही, इनका साइज़ बाइट में, कर्व के क्रम के बराबर होता है. उदाहरण के लिए, NIST P-256 कर्व के लिए, r और s को 32 बाइट तक शून्य से पैड किया जाता है.

डीईआर सिग्नेचर को ASN.1 का इस्तेमाल करके कोड में बदला जाता है:

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

खास तौर पर, एन्कोडिंग यह है:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink, हस्ताक्षर की पुष्टि करने के सबसे सही तरीकों का पालन करता है. यह सिर्फ़ DER कोड में बदले गए ECDSA हस्ताक्षर स्वीकार करता है. BER कोड में बदले गए हस्ताक्षर मान्य नहीं होते.

इससे सिग्नेचर में बदलाव करके किए जाने वाले हमलों को रोकने में मदद मिलती है. इस तरह के हमले अक्सर क्रिप्टोकरेंसी सिस्टम पर असर डालते हैं.

External Mu ML-DSA prehash values

Prehash प्रिमिटिव, मैसेज को prehash वैल्यू में बदलता है. इसके बाद, SignPrehash प्रिमिटिव इस पर हस्ताक्षर करता है. External Mu मोड में एमएल-डीएसए के लिए, RFC 9881 में बताए गए तरीके के मुताबिक, प्रीहैश वैल्यू 69 बाइट की होती है. इसका लेआउट इस तरह होता है:

0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
  • mu, ML-DSA मैसेज का प्रतिनिधि है. इसे SHAKE256(tr || 0x00 || 0x00 || message, 64) के तौर पर कैलकुलेट किया जाता है. इसमें tr, सार्वजनिक पासकोड का 64-बाइट हैश है. पहला 0x00, प्योर ML-DSA के लिए FIPS 204 डोमेन सेपरेटर है. वहीं, दूसरा 0x00, कॉन्टेक्स्ट स्ट्रिंग की लंबाई (खाली) है. tr को सार्वजनिक पासकोड से बनाया जाता है. इसलिए, mu को क्रिप्टोग्राफ़िक तरीके से उस पासकोड से जोड़ा जाता है. हालांकि, बाइंडिंग की जांच करने के लिए मूल मैसेज की ज़रूरत होती है.
  • पांच बाइट वाला प्रीफ़िक्स, Tink फ़्रेमिंग है. यह mu का हिस्सा नहीं है. यह प्रीहैश वैल्यू को किसी खास कुंजी से जोड़ता है, ताकि SignPrehash को पता चल सके कि किस कुंजी से साइन करना है. साथ ही, यह ऐसी प्रीहैश वैल्यू को अस्वीकार कर सकता है जिसके लिए उसके पास कोई कुंजी नहीं है. प्रीफ़िक्स, सामान्य मेटाडेटा होता है और यह क्रिप्टोग्राफ़िक रूप से किसी भी चीज़ से नहीं जुड़ा होता: इसे कोई भी व्यक्ति फिर से लिख सकता है.

साइन करने की प्रोसेस में, ऐसे किसी भी इनपुट को अस्वीकार कर दिया जाता है जो ठीक 69 बाइट का नहीं है, जो 0xff से शुरू नहीं होता या जिसका कुंजी आईडी, उसके कीसेट में चालू की गई कुंजी से मेल नहीं खाता.