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 फ़ॉर्म)
 
- लंबाई के प्रीफ़िक्स वाला X.509 
- 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) - पिछले लेवल में सर्टिफ़िकेट के लिए इस्तेमाल किया गया एल्गोरिदम
 
- लंबाई के प्रीफ़िक्स वाला X.509 
- flags(uint32) - फ़्लैग से पता चलता है कि इस सर्टिफ़िकेट को खुद पर भरोसा करने वाले पुराने सर्टिफ़िकेट के स्ट्रक्चर में शामिल किया जाना चाहिए या नहीं. साथ ही, यह भी पता चलता है कि किन ऑपरेशन के लिए ऐसा किया जाना चाहिए.
- signature algorithm ID(uint32) - इसकी वैल्यू, अगले लेवल में मौजूद, हस्ताक्षर किए गए डेटा सेक्शन में मौजूद वैल्यू से मेल खानी चाहिए.
- ऊपर दिए गए signed dataके ऊपर, लंबाई के प्रीफ़िक्स वालाsignature
 
- length-prefixed 
एक से ज़्यादा सर्टिफ़िकेट
एक से ज़्यादा लोगों के हस्ताक्षर करने की सुविधा काम नहीं करती. साथ ही, Google Play ऐसे ऐप्लिकेशन पब्लिश नहीं करता जिन्हें एक से ज़्यादा सर्टिफ़िकेट से साइन किया गया हो.
पुष्टि करें
Android 9 और इसके बाद के वर्शन में, APK की पुष्टि 'APK सिग्नेचर स्कीम v3', 'v2 स्कीम' या 'v1 स्कीम' के हिसाब से की जा सकती है. पुराने प्लैटफ़ॉर्म, v3 हस्ताक्षरों को अनदेखा करते हैं और v2 हस्ताक्षरों की पुष्टि करने की कोशिश करते हैं. इसके बाद, वे v1 हस्ताक्षरों की पुष्टि करते हैं.
   
पहली इमेज. APK के हस्ताक्षर की पुष्टि करने की प्रोसेस
APK सिग्नेचर स्कीम v3 की पुष्टि
- APK साइनिंग ब्लॉक ढूंढें और पुष्टि करें कि:
  - APK हस्ताक्षर करने वाले ब्लॉक के दो साइज़ फ़ील्ड में एक ही वैल्यू है.
- ZIP सेंट्रल डायरेक्ट्री के बाद, ZIP सेंट्रल डायरेक्ट्री का आखिरी रिकॉर्ड आता है.
- ज़िप सेंट्रल डायरेक्ट्री के आखिर में कोई और डेटा नहीं होता.
 
- APK साइनिंग ब्लॉक में, APK सिग्नेचर स्कीम v3 का पहला ब्लॉक ढूंढें. अगर v3 ब्लॉक मौजूद है, तो तीसरे चरण पर जाएं. अगर ऐसा नहीं है, तो v2 स्कीम का इस्तेमाल करके APK की पुष्टि करें.
- APK सिग्नेचर स्कीम v3 ब्लॉक में मौजूद हर signerके लिए, SDK टूल के कम से कम और ज़्यादा से ज़्यादा वर्शन, मौजूदा प्लैटफ़ॉर्म की रेंज में होने चाहिए:- signaturesमें से सबसे अच्छा- signature algorithm IDचुनें. सुरक्षा के लेवल का क्रम, लागू करने/प्लैटफ़ॉर्म के हर वर्शन पर निर्भर करता है.
- public keyका इस्तेमाल करके,- signaturesके- signatureकी पुष्टि करें.- signed data(- signed dataको पार्स करना अब सुरक्षित है.)
- पुष्टि करें कि हस्ताक्षर किए गए डेटा में, SDK टूल के कम से कम और ज़्यादा से ज़्यादा वर्शन, signerके लिए तय किए गए वर्शन से मेल खाते हों.
- पुष्टि करें कि digestsऔरsignaturesमें, हस्ताक्षर एल्गोरिदम आईडी की क्रम से लगाई गई सूची एक जैसी हो. (इसका मकसद, हस्ताक्षर हटाने/जोड़ने से रोकना है.)
- APK कॉन्टेंट का डाइजेस्ट कैलकुलेट करें. इसके लिए, उसी डाइजेस्ट एल्गोरिदम का इस्तेमाल करें जिसका इस्तेमाल सिग्नेचर एल्गोरिदम करता है.
- पुष्टि करें कि कैलकुलेट किया गया डाइजेस्ट, digestsकेdigestसे मेल खाता हो.
- पुष्टि करें कि certificatesके पहलेcertificateका SubjectPublicKeyInfo,public keyसे मेल खाता हो.
- अगर signerके लिए, रोटेशन का सबूत वाला एट्रिब्यूट मौजूद है, तो पुष्टि करें कि स्ट्रक्चर मान्य है और यहsigner, सूची में मौजूद आखिरी सर्टिफ़िकेट है.
 
- अगर मौजूदा प्लैटफ़ॉर्म की रेंज में एक ही signerमिला और उसsignerके लिए तीसरे चरण की पुष्टि हो गई, तो पुष्टि हो जाती है.
पुष्टि करें
यह जांचने के लिए कि आपका डिवाइस v3 के साथ ठीक से काम करता है या नहीं, PkgInstallSignatureVerificationTest.javaमें cts टेस्ट चलाएंcts/hostsidetests/appsecurity/src/android/appsecurity/cts/.
