签名工具的使用Android源码编译出来的signapk.jar既可给apk签名,也可给rom签名的。使用格式:
java –jar signapk.jar [-w] publickey.x509[.pem] privatekey.pk8 input.jar output.jar
-w 是指对ROM签名时需使用的参数
publickey.x509[.pem] 是公钥文件
privatekey.pk8 是指 私钥文件
input.jar 要签名的apk或者rom
output.jar 签名后生成的apk或者rom
signapk.java
1) main函数
main函数会生成公钥对象和私钥对象,并调用addDigestsToManifest函数生成清单对象Manifest后,再调用signFile签名。
public static void main(String[] args) {
//...
boolean signWholeFile = false;
int argstart = 0;
/*如果对ROM签名需传递-w参数*/
if (args[0].equals("-w")) {
signWholeFile = true;
argstart = 1;
}
// ...
try {
File publicKeyFile = new File(args[argstart+0]);
X509Certificate publicKey = readPublicKey(publicKeyFile);
PrivateKey privateKey = readPrivateKey(new File(args[argstart+1]));
inputJar = new JarFile(new File(args[argstart+2]), false);
outputFile = new FileOutputStream(args[argstart+3]);
/*对ROM签名,读者可自行分析,和Apk饿签名类似,但是它会添加otacert文件*/
if (signWholeFile) {
SignApk.signWholeFile(inputJar, publicKeyFile, publicKey,
privateKey, outputFile);
}
else {
JarOutputStream outputJar = new JarOutputStream(outputFile);
outputJar.setLevel(9);
/*addDigestsToManifest会生成Manifest对象,然后调用signFile进行签名*/
signFile(addDigestsToManifest(inputJar), inputJar,
publicKeyFile, publicKey, privateKey, outputJar);
outputJar.close();
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
//...
}
}
2) addDigestsToManifest
首先我们得理解Manifest文件的结构,Manifest文件里用空行分割成多个段,每个段由多个属性组成,第一个段的属性集合称为主属性集合,其它段称为普通属性集合,普通属性集合一般会有Name属性,作为该属性集合所在段的名字。Android的manifeset文件会为zip的所有文件各自建立一个段,这个段的Name属性的值就是该文件的path+文件名,另外还有一个SHA1-Digest的属性,该属性的值是对文件的sha1摘要用base64编码得到的字符串。
Manifest示例:
Manifest-Version: 1.0
Created-By: 1.6.0-rc (Sun Microsystems Inc.)
Name: res/drawable-hdpi/user_logout.png
SHA1-Digest: zkQSZbt3Tqc9myEVuxc1dzMDPCs=
Name: res/drawable-hdpi/contacts_cancel_btn_pressed.png
SHA1-Digest: mSVZvKpvKpmgUJ9oXDJaTWzhdic=
Name: res/drawable/main_head_backgroud.png
SHA1-Digest: fe1yzADfDGZvr0cyIdNpGf/ySio=
Manifest-Version属性和Created-By所在的段就是主属性集合,其它属性集合就是普通属性集合,这些普通属性集合都有Name属性&#x