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

एंड्रॉइड 11 एपीके सिग्नेचर स्कीम v4. v4 हस्ताक्षर एपीके के सभी बाइट्स पर गणना किए गए मर्कल हैश ट्री पर आधारित है। यह बिल्कुल fs-verity हैश ट्री की संरचना का अनुसरण करता है (उदाहरण के लिए, नमक को शून्य-पैडिंग और अंतिम ब्लॉक को शून्य-पैडिंग)। Android 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 APK के v3 साइनिंग ब्लॉक से लिया गया है, या, यदि मौजूद नहीं है, तो v2 ब्लॉक से लिया गया है (देखें apk_digest )

एक 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 Android SDK टूल अब v4 हस्ताक्षर फ़ाइल जेनरेट करता है। v4 हस्ताक्षर को अन्य हस्ताक्षर योजनाओं की तरह ही अक्षम किया जा सकता है। यह भी सत्यापित कर सकता है कि v4 हस्ताक्षर मान्य है या नहीं।

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

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

जब स्थापना सत्र किया जा रहा है, तो PackageManagerService incfs से साइनिंग_इन्फो ब्लॉब को पुनः प्राप्त करने के लिए एक ioctl करता है, इसे पार्स करता है और हस्ताक्षर को सत्यापित करता है।

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

apk_digest

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. V2, SHA2-256।

एपीके सिग्नेचर स्कीम v3 में लेंथ-प्रीफिक्स्ड सिग्नेचर का लेंथ-प्रीफिक्स्ड सिग्नेचर देखें।

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

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

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

  • CtsIncrementalInstallHostTestCases
    • /एंड्रॉयड/सीटीएस/होस्टसाइडटेस्ट्स/इंक्रीमेंटलइंस्टॉल

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

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

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

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

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

संकेत

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

स्थापित करना

$ ./adb install game.apk

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

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