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

एंड्रॉइड 9 एपीके कुंजी रोटेशन का समर्थन करता है, जो ऐप्स को एपीके अपडेट के हिस्से के रूप में अपनी हस्ताक्षर कुंजी बदलने की क्षमता देता है। रोटेशन को व्यावहारिक बनाने के लिए, एपीके को नई और पुरानी हस्ताक्षर कुंजी के बीच विश्वास के स्तर को इंगित करना चाहिए। कुंजी रोटेशन का समर्थन करने के लिए, हमने नई और पुरानी कुंजी का उपयोग करने की अनुमति देने के लिए एपीके हस्ताक्षर योजना को v2 से v3 तक अपडेट किया है। V3 एपीके साइनिंग ब्लॉक में समर्थित एसडीके संस्करणों और प्रूफ-ऑफ-रोटेशन संरचना के बारे में जानकारी जोड़ता है।

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

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

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

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

V3 योजना को काफी हद तक v2 योजना के समान डिज़ाइन किया गया है। इसका सामान्य प्रारूप समान है और यह समान हस्ताक्षर एल्गोरिदम आईडी , कुंजी आकार और ईसी वक्र का समर्थन करता है।

हालाँकि, v3 योजना समर्थित SDK संस्करणों और प्रूफ़-ऑफ़-रोटेशन संरचना के बारे में जानकारी जोड़ती है।

प्रारूप

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

एपीके सिग्नेचर स्कीम v3 ब्लॉक का प्रारूप v2 के अनुरूप है:

  • लंबाई-उपसर्ग signer का लंबाई-उपसर्ग अनुक्रम:
    • लंबाई-उपसर्ग signed data :
      • लंबाई-उपसर्ग अनुक्रम लंबाई-उपसर्ग digests :
        • signature algorithm ID (4 बाइट्स)
        • 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) - हस्ताक्षरित डेटा अनुभाग में minSDK मान का डुप्लिकेट - यदि वर्तमान प्लेटफ़ॉर्म सीमा में नहीं है तो इस हस्ताक्षर के सत्यापन को छोड़ने के लिए उपयोग किया जाता है। हस्ताक्षरित डेटा मान से मेल खाना चाहिए.
    • maxSDK (uint32) - हस्ताक्षरित डेटा अनुभाग में maxSDK मान का डुप्लिकेट - यदि वर्तमान प्लेटफ़ॉर्म सीमा में नहीं है तो इस हस्ताक्षर के सत्यापन को छोड़ने के लिए उपयोग किया जाता है। हस्ताक्षरित डेटा मान से मेल खाना चाहिए.
    • लंबाई-उपसर्ग वाले signatures का लंबाई-उपसर्ग क्रम:
      • signature algorithm ID (uint32)
      • signed data पर लंबाई-उपसर्ग signature
    • लंबाई-उपसर्ग वाली public key (SubjectPublicKeyInfo, ASN.1 DER फॉर्म)

प्रूफ़-ऑफ़-रोटेशन और स्व-भरोसेमंद-पुराने-प्रमाणपत्र संरचनाएँ

प्रूफ़-ऑफ़ रोटेशन संरचना ऐप्स को उन अन्य ऐप्स पर अवरुद्ध किए बिना अपने हस्ताक्षर प्रमाणपत्र को घुमाने की अनुमति देती है जिनके साथ वे संचार करते हैं। इसे पूरा करने के लिए, ऐप हस्ताक्षर में डेटा के दो नए टुकड़े होते हैं:

  • तीसरे पक्षों के लिए यह दावा कि ऐप के हस्ताक्षर प्रमाणपत्र पर वहां भी भरोसा किया जा सकता है, जहां उसके पूर्ववर्तियों पर भरोसा किया जाता है
  • ऐप के पुराने हस्ताक्षर प्रमाणपत्र जिन पर ऐप अभी भी भरोसा करता है

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

सेट में इसकी सदस्यता और गुणों को इंगित करने वाले प्रत्येक नोड में झंडे जोड़कर स्व-भरोसेमंद-पुराने-प्रमाणित डेटा संरचना का निर्माण किया जाता है। उदाहरण के लिए, एक ध्वज मौजूद हो सकता है जो दर्शाता है कि किसी दिए गए नोड पर हस्ताक्षर प्रमाणपत्र एंड्रॉइड हस्ताक्षर अनुमतियां प्राप्त करने के लिए विश्वसनीय है। यह ध्वज पुराने प्रमाणपत्र द्वारा हस्ताक्षरित अन्य ऐप्स को अभी भी नए हस्ताक्षर प्रमाणपत्र से हस्ताक्षरित ऐप द्वारा परिभाषित हस्ताक्षर अनुमति प्रदान करने की अनुमति देता है। क्योंकि संपूर्ण प्रूफ़-ऑफ़-रोटेशन विशेषता v3 signer फ़ील्ड के हस्ताक्षरित डेटा अनुभाग में रहती है, यह युक्त एपीके पर हस्ताक्षर करने के लिए उपयोग की जाने वाली कुंजी द्वारा संरक्षित होती है।

यह प्रारूप कई हस्ताक्षर कुंजियों और विभिन्न पूर्वजों के हस्ताक्षर प्रमाणपत्रों को एक में अभिसरण (एक सामान्य सिंक के लिए कई शुरुआती नोड्स) को रोकता है।

प्रारूप

रोटेशन का प्रमाण आईडी 0x3ba06f8c के तहत एपीके सिग्नेचर स्कीम v3 ब्लॉक के अंदर संग्रहीत किया जाता है। इसका प्रारूप है:

  • लंबाई-उपसर्ग levels का लंबाई-उपसर्ग अनुक्रम:
    • लंबाई-उपसर्ग signed data (पिछले प्रमाणपत्र द्वारा - यदि मौजूद है)
      • लंबाई-उपसर्ग X.509 certificate (ASN.1 DER प्रपत्र)
      • signature algorithm ID (uint32) - पिछले स्तर में प्रमाणपत्र द्वारा उपयोग किया जाने वाला एल्गोरिदम
    • flags (uint32) - झंडे यह दर्शाते हैं कि यह प्रमाणपत्र स्व-विश्वसनीय-पुराने-प्रमाण पत्र संरचना में होना चाहिए या नहीं, और किस संचालन के लिए होना चाहिए।
    • signature algorithm ID (uint32) - अगले स्तर में हस्ताक्षरित डेटा अनुभाग से मेल खाना चाहिए।
    • उपरोक्त signed data पर लंबाई-उपसर्ग signature

एकाधिक प्रमाणपत्र

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

एकाधिक हस्ताक्षरकर्ता रोटेशन विशेषता का प्रमाण

  • लंबाई-उपसर्ग sets का लंबाई-उपसर्ग अनुक्रम:
    • signed data (पिछले सेट द्वारा - यदि मौजूद है)
      • certificates की लंबाई-उपसर्ग अनुक्रम
        • लंबाई-उपसर्ग X.509 certificate (ASN.1 DER प्रपत्र)
      • signature algorithm IDs का अनुक्रम (uint32) - पिछले सेट से प्रत्येक प्रमाणपत्र के लिए एक, उसी क्रम में।
    • flags (uint32) - झंडे यह दर्शाते हैं कि प्रमाणपत्रों का यह सेट स्व-विश्वसनीय-पुराने-प्रमाणपत्र संरचना में होना चाहिए या नहीं, और किस संचालन के लिए होना चाहिए।
    • लंबाई-उपसर्ग वाले signatures का लंबाई-उपसर्ग क्रम:
      • signature algorithm ID (uint32) - हस्ताक्षरित डेटा अनुभाग से मेल खाना चाहिए
      • उपरोक्त signed data पर लंबाई-उपसर्ग signature

प्रूफ़-ऑफ़-रोटेशन संरचना में एकाधिक पूर्वज

v3 योजना एक ही ऐप के लिए एक ही हस्ताक्षर कुंजी पर घूमने वाली दो अलग-अलग कुंजियों को भी संभाल नहीं पाती है। यह एक अधिग्रहण के मामले से अलग है, जहां अधिग्रहण करने वाली कंपनी अनुमतियां साझा करने के लिए अपनी हस्ताक्षर कुंजी का उपयोग करने के लिए अधिग्रहीत ऐप को स्थानांतरित करना चाहेगी। अधिग्रहण को एक समर्थित उपयोग-मामले के रूप में देखा जाता है क्योंकि नया ऐप अपने पैकेज नाम से अलग होगा और इसमें अपनी स्वयं की प्रूफ-ऑफ-रोटेशन संरचना शामिल हो सकती है। एक ही ऐप में एक ही प्रमाणपत्र तक पहुंचने के लिए दो अलग-अलग रास्ते होने का असमर्थित मामला, कुंजी रोटेशन डिज़ाइन में बनाई गई कई धारणाओं को तोड़ देता है।

सत्यापन

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

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

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

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

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

मान्यकरण

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