android签名机制4

接着上篇,继续来分析签名过程,先看张简易的时序图:
 

主要对签名时的命令行进行分析: 
java -jar  signapk.jar  platform.x509.pem  platform.pk8 **.apk   ***.apk     
注:如果对已签名的apk执行该命令,会重新覆盖已有的签名信息,故印证前面说讲的支持多次签名,以最后一次为准

signapk代码位于android源码路径:
SignApk.java (build\tools\signapk) 

是个可执行程序,代码只有514行,具体可参考代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public static void main(String[] args) {
         if (args.length != 4 && args.length != 5 ) {
             System.err.println( "Usage: signapk [-w] " +
                     "publickey.x509[.pem] privatekey.pk8 " +
                     "input.jar output.jar" );
             System.exit( 2 );
         }
 
         boolean signWholeFile = false ;
         int argstart = 0 ;
         if (args[ 0 ].equals( "-w" )) {
             signWholeFile = true ;
             argstart = 1 ;
         }
 
         JarFile inputJar = null ;
         JarOutputStream outputJar = null ;
         FileOutputStream outputFile = null ;
 
         try {
             X509Certificate publicKey = readPublicKey( new File(args[argstart+ 0 ]));
 
             // Assume the certificate is valid for at least an hour.
             long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000 ;
 
             PrivateKey privateKey = readPrivateKey( new File(args[argstart+ 1 ]));
             inputJar = new JarFile( new File(args[argstart+ 2 ]), false );  // Don't verify.
 
             OutputStream outputStream = null ;
             if (signWholeFile) {
                 outputStream = new ByteArrayOutputStream();
             } else {
                 outputStream = outputFile = new FileOutputStream(args[argstart+ 3 ]);
             }
             outputJar = new JarOutputStream(outputStream);
             outputJar.setLevel( 9 );
 
             JarEntry je;
 
             // MANIFEST.MF
             Manifest manifest = addDigestsToManifest(inputJar);
             je = new JarEntry(JarFile.MANIFEST_NAME);
             je.setTime(timestamp);
             outputJar.putNextEntry(je);
             manifest.write(outputJar);
 
             // CERT.SF
             Signature signature = Signature.getInstance( "SHA1withRSA" );
             signature.initSign(privateKey);
             je = new JarEntry(CERT_SF_NAME);
             je.setTime(timestamp);
             outputJar.putNextEntry(je);
             writeSignatureFile(manifest,
                     new SignatureOutputStream(outputJar, signature));
 
             // CERT.RSA
             je = new JarEntry(CERT_RSA_NAME);
             je.setTime(timestamp);
             outputJar.putNextEntry(je);
             writeSignatureBlock(signature, publicKey, outputJar);
 
             // Everything else
             copyFiles(manifest, inputJar, outputJar, timestamp);
 
             outputJar.close();
             outputJar = null ;
             outputStream.flush();
 
             if (signWholeFile) {
                 outputFile = new FileOutputStream(args[argstart+ 3 ]);
                 signWholeOutputFile(((ByteArrayOutputStream)outputStream).toByteArray(),
                                     outputFile, publicKey, privateKey);
             }
         } catch (Exception e) {
             e.printStackTrace();
             System.exit( 1 );
         } finally {
             try {
                 if (inputJar != null ) inputJar.close();
                 if (outputFile != null ) outputFile.close();
             } catch (IOException e) {
                 e.printStackTrace();
                 System.exit( 1 );
             }
         }
     }

1.MANIFEST.MF:保存资源文件的摘要经base64编码后的信息---数字摘要
2.CERT.SF:保存对摘要hash后的信息----数字签名
3.CERT.RSA:保存公钥信息---数字证书

涉及到的类:
Signature.java (frameworks\base\core\java\android\content\pm)


之后设备安装apk,会校验签名,校验过程主要在PackageManagerService中实现

原作者:http://my.oschina.net/blackylin/blog/207480

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值