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

एंड्रॉइड 11 एपीके सिग्नेचर स्कीम v4 के साथ स्ट्रीमिंग-संगत हस्ताक्षर योजना का समर्थन करता है। V4 हस्ताक्षर एपीके के सभी बाइट्स पर गणना किए गए मर्कल हैश ट्री पर आधारित है। यह बिल्कुल एफएस-वेरिटी हैश ट्री की संरचना का अनुसरण करता है (उदाहरण के लिए, नमक को शून्य-पैडिंग और अंतिम ब्लॉक को शून्य-पैडिंग)। एंड्रॉइड 11 हस्ताक्षर को एक अलग फ़ाइल में संग्रहीत करता है, <apk name>.apk.idsig एक v4 हस्ताक्षर के लिए एक पूरक v2 या v3 हस्ताक्षर की आवश्यकता होती है।

फ़ाइल फ़ारमैट

सभी संख्यात्मक फ़ील्ड छोटे एंडियन में हैं। सभी फ़ील्ड अपने sizeof() के समान बाइट्स की संख्या पर कब्जा करते हैं, कोई अंतर्निहित पैडिंग या संरेखण नहीं जोड़ा जाता है।

परिभाषाओं को सरल बनाने के लिए नीचे एक सहायक संरचना दी गई है।

template <class SizeT>
struct sized_bytes {
        SizeT size;
        byte bytes[size];
};

मुख्य फ़ाइल सामग्री:

struct V4Signature {
        int32 version; // only version 2 is supported as of now
        sized_bytes<int32> hashing_info;
        sized_bytes<int32> signing_info;
        sized_bytes<int32> merkle_tree;  // optional
};

hashing_info हैश ट्री जेनरेशन + रूट हैश के लिए उपयोग किया जाने वाला पैरामीटर है:

struct hashing_info.bytes {
    int32 hash_algorithm;    // only 1 == SHA256 supported
    int8 log2_blocksize;     // only 12 (block size 4096) supported now
    sized_bytes<int32> salt; // used exactly as in fs-verity, 32 bytes max
    sized_bytes<int32> raw_root_hash; // salted digest of the first Merkle tree page
};

signing_info निम्नलिखित संरचना है:

struct signing_info.bytes {
    sized_bytes<int32> apk_digest;  // used to match with the corresponding APK
    sized_bytes<int32> x509_certificate; // ASN.1 DER form
    sized_bytes<int32> additional_data; // a free-form binary data blob
    sized_bytes<int32> public_key; // ASN.1 DER, must match the x509_certificate
    int32 signature_algorithm_id; // see the APK v2 doc for the list
    sized_bytes<int32> signature;
};
  • apk_digest एपीके के वी3 साइनिंग ब्लॉक से लिया गया है, या, यदि मौजूद नहीं है, तो वी2 ब्लॉक से लिया गया है ( एपीके_डाइजेस्ट देखें)

एक signature कोड बनाने और सत्यापित करने के लिए निम्नलिखित डेटा को बाइनरी ब्लॉब में क्रमबद्ध करना होगा और इसे हस्ताक्षरित डेटा के रूप में हस्ताक्षर/सत्यापन एल्गोरिदम में पास करना होगा:

struct V4DataForSigning {
        int32 size;
        int64 file_size; // the size of the file that's been hashed.
        hashing_info.hash_algorithm;
        hashing_info.log2_blocksize;
        hashing_info.salt;
        hashing_info.raw_root_hash;
        signing_info.apk_digest;
        signing_info.x509_certificate;
        signing_info.additional_data;
};
  1. merkle_tree एपीके का संपूर्ण मर्कल ट्री है, जिसकी गणना fs-verity दस्तावेज़ में वर्णित अनुसार की गई है।

निर्माता और उपभोक्ता

यदि आप इसे डिफ़ॉल्ट पैरामीटर के साथ चलाते हैं तो apksigner एंड्रॉइड एसडीके टूल अब v4 हस्ताक्षर फ़ाइल उत्पन्न करता है। v4 हस्ताक्षर को अन्य हस्ताक्षर योजनाओं की तरह ही अक्षम किया जा सकता है। यह यह भी सत्यापित कर सकता है कि v4 हस्ताक्षर वैध है या नहीं।

adb उम्मीद है कि adb install --incremental कमांड चलाते समय .apk.idsig फ़ाइल .apk के बगल में मौजूद होगी
यह डिफ़ॉल्ट रूप से वृद्धिशील इंस्टॉलेशन का प्रयास करने के लिए .idsig फ़ाइल का भी उपयोग करेगा, और यदि यह गुम या अमान्य है तो नियमित इंस्टॉलेशन पर वापस आ जाएगा।

जब एक इंस्टॉलेशन सत्र बनाया जाता है, तो PackageInstaller में नया स्ट्रीमिंग इंस्टॉलेशन एपीआई सत्र में फ़ाइल जोड़ते समय अलग किए गए v4 हस्ताक्षर को एक अलग तर्क के रूप में स्वीकार करता है। इस बिंदु पर, signing_info संपूर्ण ब्लॉब के रूप में incfs में पास कर दिया जाता है। Incfs ब्लॉब से रूट हैश निकालता है।

जब इंस्टॉलेशन सत्र प्रतिबद्ध किया जा रहा है, तो PackageManagerService incfs सेsigning_info ब्लॉब को पुनः प्राप्त करने के लिए एक ioctl करता है, इसे पार्स करता है और हस्ताक्षर को सत्यापित करता है।

वृद्धिशील डेटा लोडर घटक से डेटा लोडर मूल एपीआई के माध्यम से हस्ताक्षर के मर्कल ट्री भाग को स्ट्रीम करने की उम्मीद की जाती है।
package सर्विस शेल कमांड install-incremental प्रत्येक जोड़ी गई फ़ाइल के पैरामीटर के रूप में बेस64 के रूप में एन्कोड की गई स्ट्रिप्ड वी4 हस्ताक्षर फ़ाइल को स्वीकार करता है। संबंधित मर्कल ट्री को कमांड के stdin में भेजना होगा।

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

apk_digest क्रम में पहला उपलब्ध सामग्री डाइजेस्ट है:

  1. V3, 1MB ब्लॉक, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
  2. V3, 4KB ब्लॉक, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
  3. V3, 1MB ब्लॉक, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
  4. V2, SHA2-512,
  5. वी2, एसएचए2-256।

एपीके सिग्नेचर स्कीम v3 में लंबाई-उपसर्ग हस्ताक्षरों का लंबाई-उपसर्ग क्रम देखें।

एपीके सत्यापन प्रक्रिया v4
चित्र 1 : एपीके सत्यापन प्रक्रिया v4

सत्यापन और परीक्षण

फ़ीचर यूनिट टेस्ट और सीटीएस का उपयोग करके कार्यान्वयन को सत्यापित करें।

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

हस्ताक्षर प्रारूप का परीक्षण

हस्ताक्षर प्रारूप का परीक्षण करने के लिए, एक विकास वातावरण स्थापित करें और निम्नलिखित मैन्युअल परीक्षण चलाएँ:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

Android SDK (ADB और apksigner) के साथ हस्ताक्षर प्रारूप का परीक्षण

एंड्रॉइड एसडीके के साथ हस्ताक्षर प्रारूप का परीक्षण करने के लिए, एक विकास वातावरण स्थापित करें और सुनिश्चित करें कि आपने IncFS का कार्यान्वयन पूरा कर लिया है। फिर लक्ष्य भौतिक डिवाइस या एमुलेटर पर बिल्ड को फ्लैश करें। आपको एक मौजूदा एपीके जेनरेट या प्राप्त करना होगा और फिर एक डिबग साइनिंग कुंजी बनानी होगी। अंत में, बिल्ड-टूल्स फ़ोल्डर से v4 हस्ताक्षर प्रारूप के साथ एपीके पर हस्ताक्षर करें और इंस्टॉल करें।

संकेत

$ ./apksigner sign --ks debug.keystore game.apk

स्थापित करना

$ ./adb install game.apk

ये परीक्षण कहां मिल सकते हैं?

/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java