- 生成系统签名的脚本 buildkey.sh 放到源码根目录 执行
#!/bin/bash
subject='/C=CN/ST=shanghai/L=shanghai View/O=xxx/OU=ivglass/CN=xxx/emailAddress=xxx@xxx.com'
mkdir ~/.android-certs
for x in releasekey platform shared media networkstack testkey verity; do \
./development/tools/make_key ~/.android-certs/$x "$subject"; \
done
-生成key给androidstudio用
$ git clone https://github.com/getfatday/keytool-importkeypair
脚本如下:
命名成shell.sh 放到windows 的bash 下执行
#!/usr/bin/bash
read -p "Please input password >>>: " password
read -p "Please keystore name >>>: " keystore_name
read -p "Please alias name >>>: " alias_name
./keytool-importkeypair -k ./$keystore_name -p $password -pk8 platform.pk8 -cert platform.x509.pem -alias $alias_name
在bash上执行
$ sh shell.sh
Please input password >>>: xx12345678
Please keystore name >>>: xxx.keystore
Please alias name >>>: xxxkey
Importing "xxxkey" with SHA1 Fingerprint=EF:DF:D3:8B:C4:5E:E5:1D:C1:AA:14:78:5A:30:9C:7E:CD:C8:32:92
▒▒▒ڽ▒▒▒Կ▒▒ C:/Users/XUANYU~1.CHE/AppData/Local/Temp/keytool-importkeypair.RS5w/p12 ▒▒▒뵽 ./xx.keystore...
▒ѳɹ▒▒▒▒▒▒▒▒ xxkey ▒▒▒▒Ŀ▒▒
▒▒▒▒ɵ▒▒▒▒▒▒▒: 1 ▒▒▒▒Ŀ▒ɹ▒▒▒▒▒, 0 ▒▒▒▒Ŀʧ▒ܻ▒ȡ▒▒
生成的xxx.keystore 放到项目根目录
androidstudio中配置
signingConfigs {
debug {
storeFile file('E:\\code\\key\\xx\\xxx.keystore')
storePassword 'xx12345678'
keyAlias 'xxxkey'
keyPassword 'xx12345678'
}
}
其他修改:让系统使用releasekey
修改平台默认签名
build/core/config.mk路径下,修改下面变量为:
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/releasekey
system/sepolicy/private/keys.conf 和 system/sepolicy/prebuilts/api/{apilevel}/private/keys.conf下,修改:
-ENG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
-USER : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
-USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
+ENG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/releasekey.x509.pem
+USER : $DEFAULT_SYSTEM_DEV_CERTIFICATE/releasekey.x509.pem
+USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/releasekey.x509.pem
build/core/core/Makefile下修改变量为:
BUILD_VERSION_TAGS = release-keys
影响模块:ota升级、应用签名
- 如果生成的系统签名带密码
在Ubuntu环境下:
1.由platform.pk8生成platform.pem
#openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
openssl pkcs8 -inform DER -in platform.pk8 -out platform.pem
2.由platform.pem和platform.x509.pem生成platform.p12,并设置密码和Alias name
openssl pkcs12 -export -in platform.x509.pem -inkey platform.pem -out platform.p12 -password pass:Iv12345678 -name xxkey
3.生成A01.jks
keytool -importkeystore -deststorepass Iv12345678 -destkeystore xxkey.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass Iv12345678
安全格式转换?
keytool -importkeystore -srckeystore xxkey.jks -destkeystore xxkey.jks -deststoretype pkcs12
4.生成keystore
keytool -v -importkeystore -srckeystore platform.p12 -srcstoretype PKCS12 -destkeystore xxkey.keystore -deststoretype JKS
查看jks详细信息
keytool -list -v -keystore xxkey.jks
编译系统会出现如下报错
FAILED: out/soong/.intermediates/frameworks/base/media/packages/BluetoothMidiService/BluetoothMidiService/android_common/BluetoothMidiService.apk
prebuilts/jdk/jdk9/linux-x86/bin/java -Djava.library.path=(dirname out/soong/host/linux-x86/lib64/libconscrypt_openjdk_jni.so) -jar out/soong/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 out/soong/.intermediates/packages/apps/CertInstaller/CertInstaller/android_common/CertInstaller-unsigned.apk out/soong/.intermediates/packages/apps/CertInstaller/CertInstaller/android_common/CertInstaller.apk
Enter password for build/target/product/security/platform.pk8 (password will not be hidden): java.lang.NullPointerException
at com.android.signapk.SignApk.decryptPrivateKey(SignApk.java:239)
at com.android.signapk.SignApk.readPrivateKey(SignApk.java:264)
at com.android.signapk.SignApk.main(SignApk.java:1090)
[ 71% 76807/107589] //packages/screensavers/Basic:BasicDreams signapk [common]
原因其他博客也有但是没说怎么改
修改方法:
build\make\tools\signapk\src\com\android\signapk\SignApk.java
private static PKCS8EncodedKeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile)
throws GeneralSecurityException {
EncryptedPrivateKeyInfo epkInfo;
try {
epkInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey);
} catch (IOException ex) {
// Probably not an encrypted key.
return null;
}
//char[] password = readPassword(keyFile).toCharArray();
String passwordNative = "你的密码";
char[] password =passwordNative.toCharArray();
SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName());
Key key = skFactory.generateSecret(new PBEKeySpec(password));
b/tools/releasetools/common.py
@@ -1449,8 +1449,11 @@ class PasswordManager(object):
result[k] = v
else:
while True:
- result[k] = getpass.getpass(
- "Enter password for %s key> " % k).strip()
+ #result[k] = getpass.getpass(
+ # "Enter password for %s key> " % k).strip()
+ result[k] = "xxx"
if result[k]:
break
再次编译 ,成功!!
- 验证:
用xxkey.keystore签名一个app,然后安装到系统
如果签名不匹配会提示
adb install appsignnewkey.apk
Performing Streamed Install
adb: failed to install appsignnewkey.apk: Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Reconciliation failed...: Reconcile failed:
Package com.ivglass.scslam has no signatures that match those in shared user android.uid.system; ignoring!]
如果签名成功就是install sucess
- 同一套代码如何做到兼容不同的key?这个代码是关键
LOCAL_CERTIFICATE :=(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)
也就是DEFAULT_SYSTEM_DEV_CERTIFICATE定义的位置为查找key的文件夹
比如定义
DEFAULT_SYSTEM_DEV_CERTIFICATE = build/target/product/securitycustom/releasekey
LOCAL_CERTIFICATE:=platform
那么系统就会从build/target/product/securitycustom/ 目录下寻找platform.pk
所以DEFAULT_SYSTEM_DEV_CERTIFICATE 看似只定义了releasekey位置,实际上也定义了其他类型的key位置。系统详细的代码逻辑如下
ifeq ($(LOCAL_CERTIFICATE),)
# It is now a build error to add a prebuilt .apk without
# specifying a key for it.
$(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
# The magic string "PRESIGNED" means this package is already checked
# signed with its release key.
#
# By setting .CERTIFICATE but not .PRIVATE_KEY, this package will be
# mentioned in apkcerts.txt (with certificate set to "PRESIGNED")
# but the dexpreopt process will not try to re-sign the app.
PACKAGES.$(LOCAL_MODULE).CERTIFICATE := PRESIGNED
PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
else
# If this is not an absolute certificate, assign it to a generic one.
ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
LOCAL_CERTIFICATE := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)
$(info cxydebug: $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE)))
endif
PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
$(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
$(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
$(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
endif
- 遇到的问题
1、common.py 修改后没有修改可执行权限导致打包失败,开不了机
2、openssl 版本差异导致别的服务器 读取key失败 报错log:
Cannot open file:../crypto/rand/randfile.c:88
目测1.0版本稳定,1.1版本无法生存key
如何替换服务器的openssl ?
sudo wget https://www.openssl.org/source/openssl-1.0.1f.tar.gz
tar -xzvf openssl-1.0.1f.tar.gz
cd openssl-1.0.1f
./config shared zlib --prefix=/usr/local/openssl && make && make install
./config -tmake depend
cd /usr/local
ln -s openssl ssl
vi /etc/ld.so.conf 在最后面添加如下内容:
/usr/local/openssl/lib 然后执行以下命令
ldconfig
添加openssl到环境变量
在/etc/profile的最后一行,添加
export OPENSSL=/usr/local/openssl/bin
export PATH=$OPENSSL:$PATH:$HOME/bin
source /etc/profile
编译报错
POD document had syntax errors at /usr/bin/pod2man line 69. make: *** [install_docs]
执行
rm -f /usr/bin/pod2man











网友评论