一、自定义签名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/
[email protected]'
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/
[email protected]'
development/tools/make_key shared '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/
[email protected]'
development/tools/make_key media '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/
[email protected]'
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版本
我发现我这样处理之后,整个系统的算是全部按照我的要求签名了