Android签名与签名校验

1 篇文章 0 订阅
1 篇文章 0 订阅

Android签名与签名校验  

一、签名方法

方法一.源码签名(android签名方法)
备注:几乎所有的自动化签名工具都是采用的这种方法
(1)生成签名所需要的keypair:公钥与私钥
andoid源码中提供了脚本 build/target/product/security/mkkey.sh 来生成签名所需要的key
    
    
if ["$1" == ""]; then
        echo "Create a test certificate key."
        echo "Usage: $0 NAME"
        echo "Will generate NAME.pk8 and NAME.x509.pem"
        echo "  /C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com"
        return
fi
 
openssl genrsa -3 -out $1.pem 2048
 
openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 \
    -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
 
openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt

从脚本中,我们可以得知,是采用以下步骤生成keypair的。

第一步:生成长度为2048位的RSA私钥

root@bt:~/bubble example# openssl genrsa -3 -out test.pem 2048 Generating RSA private key, 2048 bit long modulus ...+++ ...................................................................................+++ e is 3 (0x3)

root@bt:~/bubble example# cat test.pem -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAxJGCXH8i3XgogreH9oMoTaqUR6zTmblWUH3dOg7lV7F+cDDC P4hPBItEumMGkwhHqdqXMrvAj3RlYVGq6iozWJDluUDzY095G7UuuiPRXr5q0vl4 t0kzPJIAon6kdbAl/0JFJqKLCeyk4aWsa4yRFBi0BWC7qg4ilLdHIZL0CFnRHK6F 9haXVxBBvDPdA06YT5MDqvThs/ZCY1BnGmBb+Srj8YJJ9Nvdxix5Dmqs5JDsn+L0 5OweZqwMcyKVMTrvjj921kJvReuHRRtVwE/xrSkusZITLZ45zySiRAi+NRR9hFlS efla/8gyCXmCYcvMDOFu827QJpbzWhKgFUWRawIBAwKCAQEAgwusPaoXPlAbAc+v +azFiRxi2nM3u9DkNak+JrSY5SD+9XXW1QWKAweDJuyvDLAvxpG6IdKAX6LuQOEc nBwiOwtD0NX3l4pQvSN0fBfg6dRHN1D7JNt3fbarFv8YTnVuqiwuGcGyBp3DQRkd nQhguBB4A5XScV7BuHova7dNWuVfLWJAgeSUckHZBUHKWkq6ETo63QBW9yqjwUKh aLAZFbyBMvmhX+9oWgKBTmmr91TIA4z0JbkpPWD8LBuTKKld6FSrOEA432+SNZvW WMjr2GxyPoE4+6kiB4EhnhQI7hOzSFHW7vD1dlxkDi+B7MvN+cgPqlZ0kvRO2v5V 5uz2GwKBgQD0s9PCzQnsdpOhUHUPAe6ztLk4Uy0y7NoWl7M/P7jEqTC73OP05oGx FVGLri3l2X7g/NVUtgSEzTUBJH/rEnBJKaCjVgtW0eaIM5Hu3x/evDdUIDeIpe6V 4D4ko6z5XuHddsURO7VOOTQXA8B2xG3bb1y8dCZ3SDN3VMX9TkQbpwKBgQDNpMdi ZjXMNRna49weee/NgQJzDEcsVFw2Kbk1vZ9xr19mSCfi/nMQKdcrap5FGBLfnbox 9lHbvWWRDHlNYcyZiB/Sq9bDJN2jwR+lXAKxLE8vM5i1DjHw46TLMz23cRUTIRl+ 19qclQmE8HHIuiw7ptia/8aqAfUFvM8h7J4EnQKBgQCjIo0siLFITw0WNaNfVp8i eHt64h4h8zwPD8zU1SXYcMsn6Jf4mavLY4uydB6ZO6nrUzjjJAMDM3irbaqctvWG G8Bs5AePNpmwImFJ6hU/KCTiwCUFw/Rj6tQYbR37lJaTpINg0nje0M1krSr52Ek8 9Oh9osRPhXek4y6o3tgSbwKBgQCJGITsRCPdeLvnQpK++/Uzq1b3XYTIOD15cSYj 07+hH5Tu2sVB/vdgG+THnGmDZWHqaSbL+Yvn05kLXaYzlohmWr/hx+SCGJPCgL/D kqx2HYofd7sjXsv17RiHd356S2NiFhD/OpG9uLEDSvaF0XLSbzsR/9nGq/iufd9r 8xQDEwKBgHVOxkAoYn4Q3DXhfeTrxpZEmg7lBTuZAg8A52xH/eVMVTSKwqw+NxfZ wrU+fGQeruGm5mmOzwOuTDwywcM8qs0/gQVsUVliCMd6IbwDnN4dsNLsZdZp1nV7 rbi0sCmk218gLOQ9p2jv9i0BS8etSEkBwRzF99KgruMGtyd4R39b -----END RSA PRIVATE KEY-----

第二步:生成x509格式的公钥证书

root@bt:~/bubble example# openssl req -new -x509 -key test.pem -out test.x509.pem -days 10000 You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California Locality Name (eg, city) []:Mountain View Organization Name (eg, company) [Internet Widgits Pty Ltd]:Android Organizational Unit Name (eg, section) []:Android Common Name (eg, YOUR name) []:Android Email Address []:android@android.com

root@bt:~/bubble example# cat test.x509.pem -----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIJALNXgLhW3YPbMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAg Fw0xMjEyMTMwNzQ1MDZaGA8xOTA0MDMyNTAxMTY1MFowgZQxCzAJBgNVBAYTAlVT MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRAw DgYDVQQKEwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRy b2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIIBIDANBgkq hkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAxJGCXH8i3XgogreH9oMoTaqUR6zTmblW UH3dOg7lV7F+cDDCP4hPBItEumMGkwhHqdqXMrvAj3RlYVGq6iozWJDluUDzY095 G7UuuiPRXr5q0vl4t0kzPJIAon6kdbAl/0JFJqKLCeyk4aWsa4yRFBi0BWC7qg4i lLdHIZL0CFnRHK6F9haXVxBBvDPdA06YT5MDqvThs/ZCY1BnGmBb+Srj8YJJ9Nvd xix5Dmqs5JDsn+L05OweZqwMcyKVMTrvjj921kJvReuHRRtVwE/xrSkusZITLZ45 zySiRAi+NRR9hFlSefla/8gyCXmCYcvMDOFu827QJpbzWhKgFUWRawIBA6OB/DCB +TAdBgNVHQ4EFgQU1aCdtEBdGQLhO7nqnaR4pCJW0q0wgckGA1UdIwSBwTCBvoAU 1aCdtEBdGQLhO7nqnaR4pCJW0q2hgZqkgZcwgZQxCzAJBgNVBAYTAlVTMRMwEQYD VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRAwDgYDVQQK EwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMSIw IAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tggkAs1eAuFbdg9swDAYD VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAq/BUGCGWpF1E7WQ/vmoDrZ4r 2XTmyHycQSFpvozeKjvlBD1ESNchEWvxOSFiFrCX/OqFwEn8sQRMClpR4fdXmKrv 5GxrXN3M6ZNOmr7cNGINNeJkKhQfepaUE9bdcdSyzQsgajF0rhYosyW48k7DW5J8 zXoBIrUgGV1KhnIPci+Jg7+QBhXGZxIOyVqDg8q8h8CJgMldyyPNdmhHDAH497Sp EgIioD/95Gk5DnrHDwlTo54vh5hT2KEjcfkMNEhXpQFgYJog+HYcJwjdFoH0ZA+P 2lZ9o6hT3Dkc1PzdgzehVVa+ys0SZ4pHMPpx2z5T9cR25wO15mC8inkcA5onqQ== -----END CERTIFICATE-----

第三步:生成符合PKCS8标注的私钥文件

root@bt:~/bubble example# openssl pkcs8 -in test.pem -topk8 -outform DER -out test.pk8 -nocrypt

可以在http://blog.csdn.net/anxuegang/article/details/6157927看到不同证书的格式的介绍

(2)用keypair签名
android源码中提供了签名生成工具,和签名所需要的公钥,私钥文件。其中 sigapk.jar为签名工具,platform.x509.pem为公钥文件,platform.pk8为私钥文件。 网上较流行的AutoSign工具就是采用的这种方法。

#!/bin/sh
MY_SDK_HOME=~/platform/android/main/mydroid/
PEM=${MY_SDK_HOME}/build/target/product/security/platform.x509.pem
PK8=${MY_SDK_HOME}/build/target/product/security/platform.pk8

if [ $# -ne 2 ]
then
    echo Usage $0 in.apk out.apk
    exit 1
fi
java -jar ${MY_SDK_HOME}/out/host/linux-x86/framework/signapk.jar  \
    ${PEM} ${PK8} $1 $2



第四步:签名

root@bt:~/bubble example/dis# java -jar signapk.jar test.x509.pem test.pk8 unsig.apk signapk.apk


第五步:优化,主要是为了 数据边界与文件的开始是内存对齐的

root@bt:~/bubble example# zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk


方法二、命令行签名(Sun 签名方法)
工具:keytool,jarsigner
第一步:生成keystore

root@bt:~# keytool -genkey -alias dani.keystore -keyalg RSA -validity 4000 -keystore dani.keystore

第二步:签名

oot@bt:~/bubble example/dis/FrozenBubbleSignapk/META-INF# jarsigner -keystore dani.keystore -digestalg SHA1 -sigalg MD5withRSA -signedjar signed.apk unsigend.apk dani.keystore

第三步:优化

root@bt:~/bubble example# zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk


二、签名过程分析
无论采取哪种签名方法,都会APK中生成META-INF文件夹,该文件夹包含三个文件
1. MANIFEST.MF
2.CERT.SF
3.CERT.RSA

生成过程如下:
第一步:.首先对文件夹中的文件采用sha1-base64生成摘要,将这些摘要信息保存在MANIFEST.MF中
我使用以下脚本对比了MANIFEST.MF中对应的值,符合

#!/usr/bin/perl use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); die "$0 requires one arguments (file pathname) . \n" if $#ARGV !=0; $filename=shift; open FH,$filename or die "cannot open $filename"; $sha1 = Digest::SHA1->new; $sha1->addfile(*FH); $digest= $sha1->b64digest; print $digest,"\n"; close FH;


第二步:.对包括MANIFEST.MF文件在内的所有文件采用sha1-base64生成摘要,方法如下。

SHA1("Name: filename"+CR+LF+"SHA1-Digest: "+SHA1(file_content)+CR+LF+CR+LF)

然后将这些摘要信息保存在CERT.MF中。
备注:采用android(Android signapk.jar与Sun jarsigner两种签名方法生成的CERT.MF文件弱有不同。


3. 对第二步中的摘要信息,采用选取的签名算法(SHA1-RSA或者MD5-RSA),用私钥进行签名,同时把公钥证书与签名信息存放在CERT.RSA中

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));


je = new JarEntry(CERT_RSA_NAME);
je.setTime(timestamp);
outputJar.putNextEntry(je);
writeSignatureBlock(signature, publicKey, outputJar);


三、签名校验
由签名生成过程,我们可以知道签名做了两件事情:
1. 完整性校验,可以发现APK包中的文件是否存在变动。
如果对文件进行修改,对应的SHA1值会发生变动。

2.APK发布作者身份唯一性校验
当在android设备上安装apk包时,会从存放在CERT.RSA中的公钥证书中提取公钥,进行RSA解密来校验安装包的身份。

使用以下命令,可以校验APk包的签名状况

root@bt:~/bubble example/dis# jarsigner -verify -certs -verbose FrozenBubble-modify-sig.apk 4689 Wed Dec 12 15:56:44 CST 2012 META-INF/MANIFEST.MF 4810 Wed Dec 12 15:56:44 CST 2012 META-INF/DANI_KEY.SF 913 Wed Dec 12 15:56:44 CST 2012 META-INF/DANI_KEY.RSA sm 29099 Wed Dec 12 15:10:22 CST 2012 assets/levels.txt X.509, CN=dani lee, OU=taomee, O=taomee, L=shanghai, ST=CA, C=CA [certificate is valid from 12/12/12 3:43 PM to 11/25/23 3:43 PM] sm 25213 Wed Dec 12 15:20:14 CST 2012 res/drawable/app_frozen_bubble.png


使用不同的key生成的签名信息会不同,不同的私钥对应不同的公钥,因此最大的区别是签名证书中存放的公钥会不同,所以我们可以通过提取CERT.RSA中的公钥来检查安装包是否被重新签名了。

具体的APk签名对比实现方法ttp://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html 可以在这里查看到,非常佩服这位博主,是个java高手,几乎每天都在更新博客。

参考:
http://www.blogjava.net/MEYE/articles/357174.html
http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值