APK सिग्नेचर स्कीम v3

Android 9 में APK के लिए पासकोड बदलने की सुविधा काम करती है. इसकी मदद से, ऐप्लिकेशन को APK अपडेट करने के दौरान, पासकोड बदलने की सुविधा मिलती है. रोटेशन को काम का बनाने के लिए, APK में नई और पुरानी, दोनों साइनिंग पासकोड के बीच भरोसे के लेवल की जानकारी होनी चाहिए. पासकोड बदलने की सुविधा के साथ काम करने के लिए, हमने APK साइनिंग स्कीम को वर्शन 2 से वर्शन 3 पर अपडेट किया है. इससे, नई और पुरानी पासकोड का इस्तेमाल किया जा सकेगा. तीसरे वर्शन में, APK साइनिंग ब्लॉक में, काम करने वाले SDK टूल के वर्शन की जानकारी और रोटेशन के सबूत का स्ट्रक्चर जोड़ा गया है.

APK साइनिंग ब्लॉक

APK के v1 फ़ॉर्मैट के साथ काम करने की सुविधा बनाए रखने के लिए, APK के v2 और v3 सिग्नेचर को APK साइनिंग ब्लॉक में सेव किया जाता है. यह ब्लॉक, ZIP सेंट्रल डायरेक्ट्री से ठीक पहले होता है.

APK साइनिंग ब्लॉक का v3 फ़ॉर्मैट, v2 के जैसा ही है. APK के v3 सिग्नेचर को आईडी-वैल्यू पेयर के तौर पर सेव किया जाता है. इसमें आईडी के तौर पर 0xf05368c0 का इस्तेमाल किया जाता है.

APK सिग्नेचर स्कीम v3 ब्लॉक

v3 स्कीम को v2 स्कीम से काफ़ी मिलता-जुलता बनाया गया है. इसका सामान्य फ़ॉर्मैट एक जैसा है. साथ ही, यह एक जैसे हस्ताक्षर वाले एल्गोरिदम आईडी, पासकोड के साइज़, और ईसी कर्व के साथ काम करता है.

हालांकि, v3 स्कीम में, काम करने वाले एसडीके वर्शन और रोटेशन के सबूत के स्ट्रक्चर के बारे में जानकारी जोड़ी गई है.

फ़ॉर्मैट करें

APK सिग्नेचर स्कीम v3 ब्लॉक, APK साइनिंग ब्लॉक में आईडी 0xf05368c0 के नीचे सेव होता है.

APK सिग्नेचर स्कीम v3 ब्लॉक का फ़ॉर्मैट, v2 ब्लॉक के फ़ॉर्मैट जैसा ही है:

  • लंबाई के प्रीफ़िक्स वाले signer का लंबाई के प्रीफ़िक्स वाला क्रम:
    • लंबाई के प्रीफ़िक्स वाला signed data:
      • लंबाई के प्रीफ़िक्स वाले digests का लंबाई के प्रीफ़िक्स वाला क्रम:
        • signature algorithm ID (चार बाइट)
        • digest (लंबाई के पहले प्रीफ़िक्स)
      • X.509 certificates का लंबाई-प्रीफ़िक्स वाला क्रम:
        • लंबाई के प्रीफ़िक्स वाला X.509 certificate (ASN.1 DER फ़ॉर्म)
      • minSDK (uint32) - अगर प्लैटफ़ॉर्म का वर्शन इस संख्या से कम है, तो इस हस्ताक्षर को अनदेखा किया जाना चाहिए.
      • maxSDK (uint32) - अगर प्लैटफ़ॉर्म का वर्शन इस संख्या से ज़्यादा है, तो इस हस्ताक्षर को अनदेखा किया जाना चाहिए.
      • लंबाई के प्रीफ़िक्स वाले additional attributes का लंबाई के प्रीफ़िक्स वाला क्रम:
        • ID (uint32)
        • value (वैरिएबल-लेंथ: अन्य एट्रिब्यूट की लंबाई - 4 बाइट)
        • ID - 0x3ba06f8c
        • value - पुरानी और नई, दोनों कुंजी के मालिकाना हक का सबूत
    • minSDK (uint32) - हस्ताक्षर किए गए डेटा सेक्शन में मौजूद, कम से कम SDK वर्शन की वैल्यू का डुप्लीकेट - अगर मौजूदा प्लैटफ़ॉर्म, तय सीमा में नहीं है, तो इस हस्ताक्षर की पुष्टि को छोड़ने के लिए इसका इस्तेमाल किया जाता है. यह हस्ताक्षर की गई डेटा वैल्यू से मेल खानी चाहिए.
    • maxSDK (uint32) - हस्ताक्षर किए गए डेटा सेक्शन में मौजूद maxSDK वैल्यू का डुप्लीकेट - इसका इस्तेमाल, अगर मौजूदा प्लैटफ़ॉर्म रेंज में नहीं है, तो इस हस्ताक्षर की पुष्टि को छोड़ने के लिए किया जाता है. यह हस्ताक्षर की गई डेटा वैल्यू से मेल खानी चाहिए.
    • लंबाई के प्रीफ़िक्स वाले signatures का लंबाई के प्रीफ़िक्स वाला क्रम:
      • signature algorithm ID (uint32)
      • लंबाई के प्रीफ़िक्स signature, signed data से ज़्यादा
    • लंबाई के प्रीफ़िक्स वाला public key (SubjectPublicKeyInfo, ASN.1 DER फ़ॉर्म)

पुरानी और नई, दोनों कुंजी के मालिकाना हक का प्रमाण और खुद पर भरोसा करने वाले पुराने सर्टिफ़िकेट के स्ट्रक्चर

रोटेशन के सबूत वाले स्ट्रक्चर की मदद से, ऐप्लिकेशन अपने हस्ताक्षर करने वाले सर्टिफ़िकेट को रोटेट कर सकते हैं. ऐसा करने पर, वे उन दूसरे ऐप्लिकेशन पर ब्लॉक नहीं होते जिनसे वे इंटरैक्ट करते हैं. ऐसा करने के लिए, ऐप्लिकेशन के हस्ताक्षर में दो नए डेटा शामिल होते हैं:

  • तीसरे पक्षों के लिए यह दावा करना कि ऐप्लिकेशन के साइनिंग सर्टिफ़िकेट पर भरोसा किया जा सकता है जहां उसके पिछले वर्शन पर भरोसा किया जाता है
  • ऐप्लिकेशन के पुराने हस्ताक्षर सर्टिफ़िकेट, जिन पर ऐप्लिकेशन अब भी भरोसा करता है

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

self-trusted-old-certs डेटा स्ट्रक्चर को बनाने के लिए, हर नोड में फ़्लैग जोड़े जाते हैं. इनसे सेट में उसकी सदस्यता और प्रॉपर्टी के बारे में पता चलता है. उदाहरण के लिए, कोई फ़्लैग मौजूद हो सकता है, जिससे पता चलता हो कि किसी नोड पर मौजूद हस्ताक्षर करने का सर्टिफ़िकेट, Android हस्ताक्षर की अनुमतियां पाने के लिए भरोसेमंद है. इस फ़्लैग की मदद से, पुराने सर्टिफ़िकेट से हस्ताक्षर किए गए अन्य ऐप्लिकेशन को, हस्ताक्षर करने की अनुमति दी जा सकती है. यह अनुमति, नए हस्ताक्षर सर्टिफ़िकेट से हस्ताक्षर किए गए ऐप्लिकेशन से तय की जाती है. पूरे 'रोटेशन का सबूत' एट्रिब्यूट, v3signer फ़ील्ड के साइन किए गए डेटा सेक्शन में मौजूद होता है. इसलिए, इसे उस कुंजी से सुरक्षित किया जाता है जिसका इस्तेमाल, उसमें मौजूद APK को साइन करने के लिए किया जाता है.

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

फ़ॉर्मैट करें

'प्रूफ़ ऑफ़ रोटेशन', APK सिग्नेचर स्कीम v3 ब्लॉक में आईडी 0x3ba06f8c के नीचे सेव होता है. इसका फ़ॉर्मैट यह है:

  • लंबाई के प्रीफ़िक्स वाले levels का लंबाई के प्रीफ़िक्स वाला क्रम:
    • length-prefixed signed data (पिछले सर्टिफ़िकेट के हिसाब से - अगर मौजूद हो)
      • लंबाई के प्रीफ़िक्स वाला X.509 certificate (ASN.1 DER फ़ॉर्म)
      • signature algorithm ID (uint32) - पिछले लेवल में सर्टिफ़िकेट के लिए इस्तेमाल किया गया एल्गोरिदम
    • flags (uint32) - फ़्लैग से पता चलता है कि इस सर्टिफ़िकेट को खुद पर भरोसा करने वाले पुराने सर्टिफ़िकेट के स्ट्रक्चर में शामिल किया जाना चाहिए या नहीं. साथ ही, यह भी पता चलता है कि किन ऑपरेशन के लिए ऐसा किया जाना चाहिए.
    • signature algorithm ID (uint32) - इसकी वैल्यू, अगले लेवल में मौजूद, हस्ताक्षर किए गए डेटा सेक्शन में मौजूद वैल्यू से मेल खानी चाहिए.
    • ऊपर दिए गए signed data के ऊपर, लंबाई के प्रीफ़िक्स वाला signature

एक से ज़्यादा सर्टिफ़िकेट

एक से ज़्यादा लोगों के हस्ताक्षर करने की सुविधा काम नहीं करती. साथ ही, Google Play ऐसे ऐप्लिकेशन पब्लिश नहीं करता जिन्हें एक से ज़्यादा सर्टिफ़िकेट से साइन किया गया हो.

पुष्टि करें

Android 9 और उसके बाद के वर्शन में, APKs की पुष्टि APK सिग्नेचर स्कीम v3, v2 स्कीम या v1 स्कीम के हिसाब से की जा सकती है. पुराने प्लैटफ़ॉर्म, v3 हस्ताक्षरों को अनदेखा करते हैं और v2 हस्ताक्षरों की पुष्टि करने की कोशिश करते हैं. इसके बाद, वे v1 हस्ताक्षरों की पुष्टि करते हैं.

APK हस्ताक्षर की पुष्टि करने की प्रोसेस

पहली इमेज. APK के हस्ताक्षर की पुष्टि करने की प्रोसेस

APK सिग्नेचर स्कीम v3 की पुष्टि

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

पुष्टि करें

यह जांचने के लिए कि आपका डिवाइस v3 के साथ ठीक से काम करता है या नहीं, PkgInstallSignatureVerificationTest.javaमें cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ के CTs टेस्ट चलाएं.