Android——編譯release版簽名系統


http://blog.csdn.net/jscese/article/details/24243171

 

    在我的第一篇博客里面http://blog.csdn.net/jscese/article/details/12184513#comments,有提到AndroidManifest.xml中的android:sharedUserId="android.uid.system",代表的意思是和系統相同的uid,可以擁有修改系統時間,文件操作等權限。

也有提到怎么單獨給一個apk簽名,這里補充一下android的簽名權限控制機制。

 
一:簽名類型

android的標准簽名key有:

testkey

media

platform

shared

以上的四種,可以在源碼的/build/target/product/security里面看到對應的密鑰,其中shared.pk8代表私鑰,shared.x509.pem公鑰,一定是成對出現的。

其中testkey是作為android編譯的時候默認的簽名key,如果系統中的apk的android.mk中沒有設置LOCAL_CERTIFICATE的值,就默認使用testkey。

而如果設置成:

LOCAL_CERTIFICATE := platform

就代表使用platform來簽名,這樣的話這個apk就擁有了和system相同的簽名,因為系統級別的簽名也是使用的platform來簽名,此時使用android:sharedUserId="android.uid.system"才有用!

 

 
二:自定義簽名Key

在/build/target/product/security目錄下有個README,里面有說怎么制作這些key以及使用問題(android4.2):

 

    The following commands were used to generate the test key pairs:  
      
      development/tools/make_key testkey  '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'  
      development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'  
      development/tools/make_key shared   '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'  
      development/tools/make_key media    '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'  
      
    The following standard test keys are currently included:  
      
    testkey -- a generic key for packages that do not otherwise specify a key.  
    platform -- a test key for packages that are part of the core platform.  
    shared -- a test key for things that are shared in the home/contacts process.  
    media -- a test key for packages that are part of the media/download system.  
      
    These test keys are used strictly in development, and should never be assumed  
    to convey any sort of validity.  When $BUILD_SECURE=true, the code should not  
    honor these keys in any context.  


從上面可以看出來在源碼下的/development/tools目錄下有個make_key的腳本,通過傳入兩個參數就可以生成一對簽名用的key。

 

其中第一個為key的名字,一般都默認成android本身有的,因為很多地方都默認使用了這些名字,我們自定義的話只需要對第二個參數動手腳,定義如下:

C ---> Country Name (2 letter code)
ST ---> State or Province Name (full name)
L ---> Locality Name (eg, city)
O ---> Organization Name (eg, company)
OU ---> Organizational Unit Name (eg, section)
CN ---> Common Name (eg, your name or your server’s hostname)
emailAddress ---> Contact email address

另外在使用上面的make_key腳本生成key的過程中會提示輸入password,我的處理是不輸入,直接enter,不要密碼!后面解釋,用自定義的key替換/security下面的。

可以看到android源碼里面的key使用的第二個參數就是上面README里面的,是公開的,所以要release版本的系統的話,肯定要有自己的簽名key才能起到一個安全控制作用。

 

 
三:修改系統默認簽名key

在上面提到如果apk中的編譯選項LOCAL_CERTIFICATE沒有設置的話,就會使用默認的testkey作為簽名key,我們可以修改成自己想要的key,按照上面的步驟制作一個releasekey,修改android配置在/build/core/config.mk中定義變量:

 

 

    DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/releasekey  


在主makefile文件里面:

 

 

    ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/releasekey)  
    BUILD_VERSION_TAGS += release-keys  

這樣的話默認的所有簽名將會使用releasekey。

 修改完之后就要編譯了,如果上面的這些key在制作的時候輸入了password就會出現如下錯誤:

  

    Enter password for build/target/product/security/releasekey.pk8 (password will not be hidden): java.lang.NullPointerException  
        at com.android.signapk.SignApk.decryptPrivateKey(SignApk.java:142)  
        at com.android.signapk.SignApk.readPrivateKey(SignApk.java:166)  
        at com.android.signapk.SignApk.main(SignApk.java:531)  
    Enter password for build/target/product/security/releasekey.pk8 (password will not be hidden): make: *** [out/target/product/gotechcn/obj/APPS/CalendarProvider_intermediates/package.apk] 錯誤 1  
    make: *** 正在等待未完成的任務....  
    Enter password for build/target/product/security/releasekey.pk8 (password will not be hidden): java.lang.NullPointerException  
        at com.android.signapk.SignApk.decryptPrivateKey(SignApk.java:142)  
        at com.android.signapk.SignApk.readPrivateKey(SignApk.java:166)  
        at com.android.signapk.SignApk.main(SignApk.java:531)  
    make: *** [out/target/product/gotechcn/obj/APPS/Calculator_intermediates/package.apk] 錯誤 1  
    Warning: AndroidManifest.xml already defines minSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.  
    Warning: AndroidManifest.xml already defines targetSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.  
     'out/target/common/obj/APPS/Calendar_intermediates/classes.dex' as 'classes.dex'...  
    Enter password for build/target/product/security/releasekey.pk8 (password will not be hidden): java.lang.NullPointerException  
        at com.android.signapk.SignApk.decryptPrivateKey(SignApk.java:142)  
        at com.android.signapk.SignApk.readPrivateKey(SignApk.java:166)  
        at com.android.signapk.SignApk.main(SignApk.java:531)  
    make: *** [out/target/product/gotechcn/obj/APPS/Calendar_intermediates/package.apk] 錯誤 1  
    ^Cmake: *** [out/target/product/gotechcn/obj/APPS/BasicDreams_intermediates/package.apk] 錯誤 130  

 

我在網上找到了合理的解釋:

其實會出現這個錯誤的最根本的原因是多線程的問題。在編譯的時候為了加速一般都會執行make -jxxx,這樣本來需要手動輸入密碼的時候,由於其它線程的運行,就會導致影響當前的輸入終端,所以就會導致密碼無法輸入的情況!

再編譯完成之后也可以在build.prop中查看到變量:

 

    ro.build.tags=release-keys  


這樣處理了之后編譯出來的都是簽名過的了,系統才算是release版本

我發現我這樣處理之后,整個系統的算是全部按照我的要求簽名了。

 
四:其它

網上看到還有另外的簽名release辦法,但是應該是針對另外的版本的,借用學習一下: 

 

    make -j4 PRODUCT-product_modul-user dist  



這個怎么跟平時的編譯不一樣,后面多了兩個參數PRODUCT-product_modul-user 和 dist. 編譯完成之后回在源碼/out/dist/目錄內生成個product_modul-target_files開頭的zip文件.這就是我們需要進行簽名的文件系統.

  

我的product_modul 是full_gotechcn,后面加“-user”代表的是最終用戶版本,關於這個命名以及product_modul等可參考http://blog.csdn.net/jscese/article/details/23931159

 

編譯出需要簽名的zip壓縮包之后,就是利用/security下面的准備的key進行簽名了:

  

    ./build/tools/releasetools/sign_target_files_apks -d /build/target/product/security  out/dist/full_gotechcn-target_files.zip   out/dist/signed_target_files.zip  


簽名目標文件 輸出成signed_target_files.zip

 

如果出現某些apk出錯,可以通過在full_gotechcn-target_files.zip前面加參數"-e <apkname>=" 來過濾這些apk.

然后再通過image的腳本生成imag的zip文件,這種方式不適用與我目前的工程源碼,沒有做過多驗證

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM