APK हस्ताक्षर योजना v2

एपीके सिग्नेचर स्कीम v2 एक संपूर्ण-फ़ाइल हस्ताक्षर योजना है जो सत्यापन गति को बढ़ाती है और एपीके के संरक्षित हिस्सों में किसी भी बदलाव का पता लगाकर अखंडता की गारंटी को मजबूत करती है

एपीके सिग्नेचर स्कीम v2 का उपयोग करके हस्ताक्षर करने से ज़िप सेंट्रल डायरेक्ट्री अनुभाग से ठीक पहले एपीके फ़ाइल में एक एपीके साइनिंग ब्लॉक डाला जाता है। एपीके साइनिंग ब्लॉक के अंदर, वी2 हस्ताक्षर और हस्ताक्षरकर्ता पहचान जानकारी एपीके सिग्नेचर स्कीम वी2 ब्लॉक में संग्रहीत की जाती है।

हस्ताक्षर करने से पहले और बाद में एपीके

चित्र 1. हस्ताक्षर करने से पहले और बाद में एपीके

एपीके सिग्नेचर स्कीम v2 को एंड्रॉइड 7.0 (नूगट) में पेश किया गया था। एंड्रॉइड 6.0 (मार्शमैलो) और पुराने उपकरणों पर एपीके को इंस्टॉल करने योग्य बनाने के लिए, एपीके को v2 योजना के साथ हस्ताक्षरित होने से पहले JAR हस्ताक्षर का उपयोग करके हस्ताक्षरित किया जाना चाहिए।

एपीके साइनिंग ब्लॉक

वी1 एपीके प्रारूप के साथ बैकवर्ड-संगतता बनाए रखने के लिए, वी2 और नए एपीके हस्ताक्षर एपीके साइनिंग ब्लॉक के अंदर संग्रहीत किए जाते हैं, एपीके सिग्नेचर स्कीम वी2 का समर्थन करने के लिए एक नया कंटेनर पेश किया गया है। एपीके फ़ाइल में, एपीके साइनिंग ब्लॉक ज़िप सेंट्रल डायरेक्टरी के ठीक पहले स्थित होता है, जो फ़ाइल के अंत में स्थित होता है।

ब्लॉक में आईडी-वैल्यू जोड़े इस तरह से लपेटे गए हैं जिससे एपीके में ब्लॉक का पता लगाना आसान हो जाता है। एपीके के v2 हस्ताक्षर को आईडी 0x7109871a के साथ एक आईडी-वैल्यू जोड़ी के रूप में संग्रहीत किया जाता है।

प्रारूप

एपीके साइनिंग ब्लॉक का प्रारूप इस प्रकार है (सभी संख्यात्मक फ़ील्ड छोटे-छोटे हैं):

  • बाइट्स में size of block (इस फ़ील्ड को छोड़कर) (uint64)
  • Uint64-लंबाई-उपसर्ग आईडी-मान जोड़े का अनुक्रम:
    • ID (uint32)
    • value (चर-लंबाई: जोड़ी की लंबाई - 4 बाइट्स)
  • बाइट्स में size of block —पहले फ़ील्ड के समान (uint64)
  • magic "एपीके सिग ब्लॉक 42" (16 बाइट्स)

एपीके को पहले ज़िप सेंट्रल डायरेक्ट्री की शुरुआत ढूंढकर पार्स किया जाता है (फ़ाइल के अंत में सेंट्रल डायरेक्ट्री रिकॉर्ड का ज़िप एंड ढूंढकर, फिर रिकॉर्ड से सेंट्रल डायरेक्ट्री का स्टार्ट ऑफसेट पढ़कर)। magic मान यह स्थापित करने का एक त्वरित तरीका प्रदान करता है कि केंद्रीय निर्देशिका से पहले जो है वह संभवतः एपीके साइनिंग ब्लॉक है। size of block तब कुशलतापूर्वक फ़ाइल में ब्लॉक की शुरुआत को इंगित करता है।

ब्लॉक की व्याख्या करते समय अज्ञात आईडी वाले आईडी-मूल्य जोड़े को नजरअंदाज किया जाना चाहिए।

एपीके सिग्नेचर स्कीम v2 ब्लॉक

एपीके पर एक या अधिक हस्ताक्षरकर्ताओं/पहचानकर्ताओं द्वारा हस्ताक्षर किए जाते हैं, प्रत्येक को एक हस्ताक्षर कुंजी द्वारा दर्शाया जाता है। यह जानकारी एपीके सिग्नेचर स्कीम v2 ब्लॉक के रूप में संग्रहीत है। प्रत्येक हस्ताक्षरकर्ता के लिए, निम्नलिखित जानकारी संग्रहीत की जाती है:

  • (हस्ताक्षर एल्गोरिथ्म, डाइजेस्ट, हस्ताक्षर) टुपल्स। एपीके की सामग्री की अखंडता जांच से हस्ताक्षर सत्यापन को अलग करने के लिए डाइजेस्ट को संग्रहीत किया जाता है।
  • हस्ताक्षरकर्ता की पहचान का प्रतिनिधित्व करने वाली X.509 प्रमाणपत्र श्रृंखला।
  • कुंजी-मूल्य जोड़े के रूप में अतिरिक्त विशेषताएँ।

प्रत्येक हस्ताक्षरकर्ता के लिए, एपीके को प्रदान की गई सूची से समर्थित हस्ताक्षर का उपयोग करके सत्यापित किया जाता है। अज्ञात हस्ताक्षर एल्गोरिदम वाले हस्ताक्षरों को नजरअंदाज कर दिया जाता है। यह प्रत्येक कार्यान्वयन पर निर्भर करता है कि एकाधिक समर्थित हस्ताक्षर सामने आने पर किस हस्ताक्षर का उपयोग किया जाए। यह भविष्य में पिछड़े-संगत तरीके से मजबूत हस्ताक्षर विधियों को पेश करने में सक्षम बनाता है। सुझाया गया तरीका सबसे मजबूत हस्ताक्षर को सत्यापित करना है।

प्रारूप

एपीके सिग्नेचर स्कीम v2 ब्लॉक को आईडी 0x7109871a के तहत एपीके साइनिंग ब्लॉक के अंदर संग्रहीत किया जाता है।

एपीके सिग्नेचर स्कीम v2 ब्लॉक का प्रारूप इस प्रकार है (सभी संख्यात्मक मान छोटे-छोटे हैं, सभी लंबाई-उपसर्ग फ़ील्ड लंबाई के लिए uint32 का उपयोग करते हैं):

  • लंबाई-उपसर्ग signer का लंबाई-उपसर्ग अनुक्रम:
    • लंबाई-उपसर्ग signed data :
      • लंबाई-उपसर्ग अनुक्रम लंबाई-उपसर्ग digests :
      • X.509 certificates की लंबाई-उपसर्ग अनुक्रम:
        • लंबाई-उपसर्ग X.509 certificate (ASN.1 DER प्रपत्र)
      • लंबाई-उपसर्ग लंबाई-उपसर्ग additional attributes का अनुक्रम:
        • ID (uint32)
        • value (चर-लंबाई: अतिरिक्त विशेषता की लंबाई - 4 बाइट्स)
    • लंबाई-उपसर्ग वाले signatures का लंबाई-उपसर्ग क्रम:
      • signature algorithm ID (uint32)
      • signed data पर लंबाई-उपसर्ग signature
    • लंबाई-उपसर्ग वाली public key (SubjectPublicKeyInfo, ASN.1 DER फॉर्म)

हस्ताक्षर एल्गोरिथम आईडी

  • 0x0101—RSASSA-PSS SHA2-256 डाइजेस्ट के साथ, SHA2-256 MGF1, 32 बाइट्स नमक, ट्रेलर: 0xbc
  • 0x0102—RSASSA-PSS SHA2-512 डाइजेस्ट के साथ, SHA2-512 MGF1, 64 बाइट्स नमक, ट्रेलर: 0xbc
  • 0x0103—RSASSA-PKCS1-v1_5 SHA2-256 डाइजेस्ट के साथ। यह उन बिल्ड सिस्टम के लिए है जिनके लिए नियतात्मक हस्ताक्षर की आवश्यकता होती है।
  • 0x0104—RSASSA-PKCS1-v1_5 SHA2-512 डाइजेस्ट के साथ। यह उन बिल्ड सिस्टम के लिए है जिनके लिए नियतात्मक हस्ताक्षर की आवश्यकता होती है।
  • 0x0201—SHA2-256 डाइजेस्ट के साथ ECDSA
  • 0x0202—SHA2-512 डाइजेस्ट के साथ ECDSA
  • 0x0301—SHA2-256 डाइजेस्ट के साथ DSA

उपरोक्त सभी हस्ताक्षर एल्गोरिदम एंड्रॉइड प्लेटफ़ॉर्म द्वारा समर्थित हैं। हस्ताक्षर उपकरण एल्गोरिदम के एक सबसेट का समर्थन कर सकते हैं।

समर्थित कुंजी आकार और ईसी वक्र:

  • आरएसए: 1024, 2048, 4096, 8192, 16384
  • ईसी: एनआईएसटी पी-256, पी-384, पी-521
  • डीएसए: 1024, 2048, 3072

अखंडता-सुरक्षित सामग्री

एपीके सामग्री की सुरक्षा के प्रयोजनों के लिए, एक एपीके में चार खंड होते हैं:

  1. ज़िप प्रविष्टियों की सामग्री (ऑफ़सेट 0 से एपीके साइनिंग ब्लॉक की शुरुआत तक)
  2. एपीके साइनिंग ब्लॉक
  3. ज़िप केंद्रीय निर्देशिका
  4. केंद्रीय निर्देशिका का ज़िप अंत

हस्ताक्षर करने के बाद एपीके अनुभाग

चित्र 2. हस्ताक्षर करने के बाद एपीके अनुभाग

एपीके सिग्नेचर स्कीम v2 सेक्शन 1, 3, 4 की अखंडता और सेक्शन 2 के अंदर मौजूद एपीके सिग्नेचर स्कीम v2 ब्लॉक के signed data ब्लॉक की सुरक्षा करता है।

अनुभाग 1, 3, और 4 की अखंडता signed data ब्लॉकों में संग्रहीत उनकी सामग्री के एक या अधिक डाइजेस्ट द्वारा संरक्षित है, जो बदले में, एक या अधिक हस्ताक्षरों द्वारा संरक्षित हैं।

खंड 1, 3, और 4 के डाइजेस्ट की गणना दो-स्तरीय मर्कल ट्री के समान निम्नानुसार की जाती है। प्रत्येक अनुभाग को लगातार 1 एमबी (2 20 बाइट्स) खंडों में विभाजित किया गया है। प्रत्येक अनुभाग में अंतिम भाग छोटा हो सकता है। प्रत्येक चंक के डाइजेस्ट की गणना बाइट 0xa5 के संयोजन, बाइट्स में चंक की लंबाई (लिटिल-एंडियन uint32), और चंक की सामग्री पर की जाती है। शीर्ष-स्तरीय डाइजेस्ट की गणना बाइट 0x5a के संयोजन, टुकड़ों की संख्या (लिटिल-एंडियन uint32) और टुकड़ों के डाइजेस्ट के संयोजन के आधार पर की जाती है, जिस क्रम में टुकड़े एपीके में दिखाई देते हैं। डाइजेस्ट की गणना टुकड़ों में की जाती है ताकि इसे समानांतर करके गणना को तेज किया जा सके।

एपीके डाइजेस्ट

चित्र 3. एपीके डाइजेस्ट

धारा 4 (केंद्रीय निर्देशिका का ज़िप अंत) की सुरक्षा ज़िप केंद्रीय निर्देशिका के ऑफसेट वाले अनुभाग द्वारा जटिल है। जब एपीके साइनिंग ब्लॉक का आकार बदलता है, तो ऑफसेट बदल जाता है, उदाहरण के लिए, जब कोई नया हस्ताक्षर जोड़ा जाता है। इस प्रकार, जब केंद्रीय निर्देशिका के ज़िप अंत पर डाइजेस्ट की गणना की जाती है, तो ज़िप केंद्रीय निर्देशिका के ऑफ़सेट वाले फ़ील्ड को एपीके साइनिंग ब्लॉक के ऑफ़सेट वाले क्षेत्र के रूप में माना जाना चाहिए।

रोलबैक सुरक्षा

एक हमलावर एंड्रॉइड प्लेटफ़ॉर्म पर v2-हस्ताक्षरित एपीके को v1-हस्ताक्षरित एपीके के रूप में सत्यापित करने का प्रयास कर सकता है जो v2-हस्ताक्षरित एपीके को सत्यापित करने का समर्थन करता है। इस हमले को कम करने के लिए, v2-हस्ताक्षरित APK जो v1-हस्ताक्षरित भी हैं, उनकी META-INF/*.SF फ़ाइलों के मुख्य अनुभाग में एक X-Android-APK-Signed विशेषता होनी चाहिए। विशेषता का मान एपीके हस्ताक्षर योजना आईडी का अल्पविराम से अलग किया गया सेट है (इस योजना की आईडी 2 है)। वी1 हस्ताक्षर को सत्यापित करते समय, एपीके सत्यापनकर्ता को उन एपीके को अस्वीकार करने की आवश्यकता होती है जिनके पास एपीके हस्ताक्षर योजना के लिए हस्ताक्षर नहीं है जिसे सत्यापनकर्ता इस सेट से पसंद करता है (उदाहरण के लिए, वी2 योजना)। यह सुरक्षा इस तथ्य पर निर्भर करती है कि META-INF/*.SF फ़ाइलों की सामग्री v1 हस्ताक्षरों द्वारा सुरक्षित है। JAR हस्ताक्षरित APK सत्यापन पर अनुभाग देखें।

एक हमलावर एपीके सिग्नेचर स्कीम v2 ब्लॉक से मजबूत हस्ताक्षरों को छीनने का प्रयास कर सकता है। इस हमले को कम करने के लिए, हस्ताक्षर एल्गोरिदम आईडी की सूची जिसके साथ एपीके पर हस्ताक्षर किए जा रहे थे, signed data ब्लॉक में संग्रहीत की जाती है जो प्रत्येक हस्ताक्षर द्वारा संरक्षित होती है।

सत्यापन

एंड्रॉइड 7.0 और बाद के संस्करण में, एपीके को एपीके सिग्नेचर स्कीम v2+ या JAR साइनिंग (v1 स्कीम) के अनुसार सत्यापित किया जा सकता है। पुराने प्लेटफ़ॉर्म v2 हस्ताक्षरों को अनदेखा करते हैं और केवल v1 हस्ताक्षरों को सत्यापित करते हैं।

एपीके हस्ताक्षर सत्यापन प्रक्रिया

चित्र 4. एपीके हस्ताक्षर सत्यापन प्रक्रिया (लाल रंग में नए चरण)

एपीके हस्ताक्षर योजना v2 सत्यापन

  1. एपीके साइनिंग ब्लॉक का पता लगाएं और सत्यापित करें कि:
    1. एपीके साइनिंग ब्लॉक के दो आकार फ़ील्ड में समान मान होते हैं।
    2. ज़िप सेंट्रल डायरेक्ट्री के तुरंत बाद सेंट्रल डायरेक्ट्री रिकॉर्ड का ज़िप अंत आता है।
    3. केंद्रीय निर्देशिका के ज़िप अंत का अनुसरण अधिक डेटा द्वारा नहीं किया जाता है।
  2. एपीके साइनिंग ब्लॉक के अंदर पहला एपीके सिग्नेचर स्कीम v2 ब्लॉक ढूंढें। यदि v2 ब्लॉक मौजूद है, तो चरण 3 पर आगे बढ़ें। अन्यथा, v1 योजना का उपयोग करके एपीके को सत्यापित करने के लिए वापस आएं।
  3. एपीके सिग्नेचर स्कीम v2 ब्लॉक में प्रत्येक signer के लिए:
    1. signatures में से सबसे मजबूत समर्थित signature algorithm ID चुनें। शक्ति क्रम प्रत्येक कार्यान्वयन/प्लेटफ़ॉर्म संस्करण पर निर्भर है।
    2. public key उपयोग करके signed data के विरुद्ध signatures से संबंधित signature सत्यापित करें। ( signed data पार्स करना अब सुरक्षित है।)
    3. सत्यापित करें कि digests और signatures में हस्ताक्षर एल्गोरिथ्म आईडी की क्रमबद्ध सूची समान है। (यह हस्ताक्षर को अलग करने/जोड़ने से रोकने के लिए है।)
    4. सिग्नेचर एल्गोरिदम द्वारा उपयोग किए गए डाइजेस्ट एल्गोरिदम के समान डाइजेस्ट एल्गोरिदम का उपयोग करके एपीके सामग्री के डाइजेस्ट की गणना करें
    5. सत्यापित करें कि गणना किया गया डाइजेस्ट digests से संबंधित digest के समान है।
    6. सत्यापित करें कि certificates के पहले certificate का SubjectPublicKeyInfo public key के समान है।
  4. यदि कम से कम एक signer पाया गया तो सत्यापन सफल हो जाता है और प्रत्येक पाए गए signer के लिए चरण 3 सफल हो जाता है।

ध्यान दें : यदि चरण 3 या 4 में विफलता होती है तो एपीके को v1 योजना का उपयोग करके सत्यापित नहीं किया जाना चाहिए।

JAR-हस्ताक्षरित APK सत्यापन (v1 योजना)

JAR-हस्ताक्षरित APK एक मानक हस्ताक्षरित JAR है, जिसमें META-INF/MANIFEST.MF में सूचीबद्ध बिल्कुल प्रविष्टियाँ होनी चाहिए और जहाँ सभी प्रविष्टियों पर हस्ताक्षरकर्ताओं के एक ही सेट द्वारा हस्ताक्षर किए जाने चाहिए। इसकी अखंडता को निम्नानुसार सत्यापित किया गया है:

  1. प्रत्येक हस्ताक्षरकर्ता को META-INF/<signer>.SF और META-INF/<signer>.(RSA|DSA|EC) JAR प्रविष्टि द्वारा दर्शाया जाता है।
  2. <हस्ताक्षरकर्ता>.(आरएसए|डीएसए|ईसी) एक PKCS #7 CMS कंटेंटइन्फो है जिसमें साइनडडेटा संरचना है जिसके हस्ताक्षर <हस्ताक्षरकर्ता>.एसएफ फ़ाइल पर सत्यापित हैं।
  3. <signer>.SF फ़ाइल में META-INF/MANIFEST.MF का संपूर्ण फ़ाइल डाइजेस्ट और META-INF/MANIFEST.MF के प्रत्येक अनुभाग का डाइजेस्ट शामिल है। MANIFEST.MF का संपूर्ण फ़ाइल डाइजेस्ट सत्यापित है। यदि वह विफल हो जाता है, तो इसके बजाय प्रत्येक MANIFEST.MF अनुभाग का डाइजेस्ट सत्यापित किया जाता है।
  4. META-INF/MANIFEST.MF में प्रत्येक अखंडता-संरक्षित JAR प्रविष्टि के लिए, एक संबंधित नामित अनुभाग होता है जिसमें प्रविष्टि की असम्पीडित सामग्री का डाइजेस्ट होता है। ये सभी डाइजेस्ट सत्यापित हैं।
  5. यदि एपीके में JAR प्रविष्टियाँ हैं जो MANIFEST.MF में सूचीबद्ध नहीं हैं और JAR हस्ताक्षर का हिस्सा नहीं हैं, तो APK सत्यापन विफल हो जाता है।

सुरक्षा श्रृंखला इस प्रकार <signer>.(RSA|DSA|EC) -> <signer>.SF -> MANIFEST.MF -> प्रत्येक अखंडता-संरक्षित JAR प्रविष्टि की सामग्री है।