轉(zhuǎn)載:
http://blog.csdn.net/kickxxx/article/details/18252881
http://www.cloudchou.com/android/post-379.html
前言
這些天有人問我關(guān)于APK或者ROM簽名的原理,因?yàn)橄惹敖佑|過簽名的東西,就想當(dāng)然地認(rèn)為在META-INF下存在3個(gè)文件,
一個(gè)是清單文件MANIFEST.MF,一個(gè)是簽名后的CERT.SF,一個(gè)是公鑰文件CERT.RSA,網(wǎng)上不少資料也是這樣的觀點(diǎn)。后來查看了簽名工
具的源代碼才發(fā)現(xiàn)大錯(cuò)特錯(cuò),CERT.SF根本不是用私鑰對(duì)MANIFSET.MF簽名后的文件,只是對(duì)MANIFEST.MF的每個(gè)條目再次計(jì)算摘要后
的文件。現(xiàn)在想想凡事不可輕易斷言,還是實(shí)事求是才能找到真理。接下來將根據(jù)源碼詳細(xì)分析APK或者ROM簽名的原理。
首先我們得知道什么是摘要,摘要是指采用單向Hash函數(shù)對(duì)數(shù)據(jù)進(jìn)行計(jì)算生成的固定長(zhǎng)度的Hash值,摘要算法有Md5,Sha1等,Md5生成的
Hash值是128位的數(shù)字,即16個(gè)字節(jié),用十六進(jìn)制表示是32個(gè)字符,Sha1生成的Hash值是160位的數(shù)字,即20個(gè)字節(jié),用十六進(jìn)制表示是
40個(gè)字符。我們是不能通過摘要推算出用于計(jì)算摘要的數(shù)據(jù),如果修改了數(shù)據(jù),那么它的摘要一定會(huì)變化(其實(shí)這句話并不正確,只是很難正好找到不同的數(shù)據(jù),
而他們的摘要值正好相等)。摘要經(jīng)常用于驗(yàn)證數(shù)據(jù)的完整性,很多下載網(wǎng)站都會(huì)列出下載文件的md5值或者sha1值。
摘要和簽名沒有任何關(guān)系,網(wǎng)上常常將摘要和簽名混為一談,這是錯(cuò)誤的。簽名和數(shù)字簽名是同一個(gè)概念,是指信息的發(fā)送者用自己的私鑰對(duì)消息摘要加密產(chǎn)
生一個(gè)字符串,加密算法確保別人無法偽造生成這段字符串,這段數(shù)字串也是對(duì)信息的發(fā)送者發(fā)送信息真實(shí)性的一個(gè)有效證明。其他發(fā)送者用他們的私鑰對(duì)同一個(gè)消
息摘要加密會(huì)得到不同的簽名,接收者只有使用發(fā)送者簽名時(shí)使用的私鑰對(duì)應(yīng)的公鑰解密簽名數(shù)據(jù)才能得到消息摘要,否則得到的不是正確的消息摘要。
數(shù)字簽名是非對(duì)稱密鑰加密技術(shù)+數(shù)字摘要技術(shù)的結(jié)合。
數(shù)字簽名技術(shù)是將信息摘要用發(fā)送者的私鑰加密,和原文以及公鑰一起傳送給接收者。接收者只有用發(fā)送者的公鑰才能解密被加密的信息摘要,然后接收者用相同的Hash函數(shù)對(duì)收到的原文產(chǎn)生一個(gè)信息摘要,與解密的信息摘要做比對(duì)。如果相同,則說明收到的信息是完整的,在傳輸過程中沒有被修改;不同則說明信息被修改過,因此數(shù)字簽名能保證信息的完整性。并且由于只有發(fā)送者才有加密摘要的私鑰,所以我們可以確定信息一定是發(fā)送者發(fā)送的。
另外還需要理解一個(gè)概念:數(shù)字證書。數(shù)字證書是一個(gè)經(jīng)證書授權(quán)中心數(shù)字簽名的包含公鑰及其擁有者信息的文件。數(shù)字證書的格式普遍采用的是X.509V3國(guó)際標(biāo)準(zhǔn),一個(gè)標(biāo)準(zhǔn)的X.509數(shù)字證書包含以下一些內(nèi)容:證書的版本信息:
1)證書的序列號(hào),每個(gè)證書都有一個(gè)唯一的證書序列號(hào);2)證書所使用的簽名算法;3)證書的發(fā)行機(jī)構(gòu)名稱,命名規(guī)則一般采用X.500格式;4)證書的
有效期,通用的證書一般采用UTC時(shí)間格式,它的計(jì)時(shí)范圍為1950-2049;5)證書所有人的名稱,命名規(guī)則一般采用X.500格式;6)證書所有人
的公開密鑰;7)證書發(fā)行者對(duì)證書的簽名。
CERT.RSA包含了數(shù)字簽名以及開發(fā)者的數(shù)字證書。CERT.RSA里的數(shù)字簽名是指對(duì)CERT.SF的摘要采用私鑰加密后的數(shù)
據(jù),Android系統(tǒng)安裝apk時(shí)會(huì)對(duì)CERT.SF計(jì)算摘要,然后使用CERT.RSA里的公鑰對(duì)CERT.RSA里的數(shù)字簽名解密得到一個(gè)摘要,比
較這兩個(gè)摘要便可知道該apk是否有正確的簽名,也就說如果其他人修改了apk并沒有重新簽名是會(huì)被檢查出來的。
需注意Android平臺(tái)的證書是自簽名的,也就說不需要權(quán)威機(jī)構(gòu)簽發(fā),數(shù)字證書的發(fā)行機(jī)構(gòu)和所有人是相同的,都是開發(fā)者自己,開發(fā)者生成公私鑰對(duì)后不需要提交到權(quán)威機(jī)構(gòu)進(jìn)行校驗(yàn)。
總結(jié):
一個(gè)xxx.apk解壓后有METO_INF目錄,里面有三個(gè)文件
1.一個(gè)是清單文件MANIFEST.MF
2.一個(gè)是簽名后的CERT.SF
3.一個(gè)是公鑰文件CERT.RSA
轉(zhuǎn)載:http://janrone.com/2015/12/29/%E6%9F%A5%E7%9C%8Bapk%E7%AD%BE%E5%90%8D-%E5%92%8C-keystore-%E7%9A%84%E4%BF%A1%E6%81%AF/
$ keytool -list -v -keystore debug.keystore
$ keytool -list -v -keystore debug.keystore
Enter keystore password:
*****************? WARNING WARNING WARNING? *****************
* The integrity of the information stored in your keystore? *
* has NOT been verified!? In order to verify its integrity, *
* you must provide your keystore password.? ? ? ? ? ? ? ? ? *
*****************? WARNING WARNING WARNING? *****************
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: androiddebugkey
Creation date: Apr 8, 2015
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 509aeb88
Valid from: Wed Apr 08 20:48:48 CST 2015 until: Fri Mar 31 20:48:48 CST 2045
Certificate fingerprints:
MD5:? 38:43:E1:B6:AB:F2:7F:80:93:CD:E5:EF:75:B9:A5:6C
SHA1: 9D:53:DB:6C:DA:D4:08:B3:D4:A6:E5:26:17:BD:80:FA:5A:E4:4F:AB
SHA256: D5:FF:04:4A:A2:F8:A4:EA:2A:44:53:28:0C:20:16:45:E8:71:AC:B1:74:76:F6:B4:01:90:86:83:73:E0:B0:8A
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: B2 FF B2 0D 9C 54 BA BA? A2 EF E3 BA E2 47 90 7F? .....T.......G..
0010: 17 8A 35 A8? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..5.
]
]
*******************************************
2、查看三方應(yīng)用或是系統(tǒng)應(yīng)用簽名
打開待查看的apk,將其中META-INF文件夾解壓出來,得到其中的CERT.RSA文件
$ keytool -printcert -file META-INF/CERT.RSA
打開待查看的apk,將其中META-INF文件夾解壓出來,得到其中的CERT.RSA文件$ keytool -printcert -file META-INF/CERT.RSAOwner: CN=Android Debug, O=Android, C=USIssuer: CN=Android Debug, O=Android, C=USSerial number: 514ab2e1Valid from: Thu Mar 21 15:12:33 CST 2013 until: Sat Mar 14 15:12:33 CST 2043Certificate fingerprints:(Md5生成的Hash值是128位的數(shù)字,即16個(gè)字節(jié),用十六進(jìn)制表示是32個(gè)字符,Sha1生成的Hash值是160位的數(shù)字,即20個(gè)字節(jié),用十六進(jìn)制表示是40個(gè)字符)MD5:? E0:F4:90:EE:CD:77:17:0E:B8:C4:AC:64:B2:F6:FC:83SHA1: 7F:E5:11:D8:37:4F:DA:D7:75:EA:A5:8C:47:06:85:95:6D:1D:3F:2BSignature algorithm name: SHA1withRSAVersion: 3
jarsigner -verbose -keystore [keystorePath] -signedjar [apkOut] [apkIn] [alias]
jarsigner命令格式:-verbose輸出詳細(xì)信息 -keystore密鑰庫位置 -signedjar要生成的文件 要簽名的文件 密鑰庫文件
keystorePath參數(shù)代表keyStore的絕對(duì)路徑,如D:\keystore
apkOut參數(shù)代表簽名后的apk路徑,如D:\signed.apk
apkin參數(shù)代表在騰訊應(yīng)用中心下載的未簽名apk,默認(rèn)名稱為tap_unsign.apk
alias參數(shù)代表簽名用的alias名稱(創(chuàng)建keyStore時(shí)所填寫),如timdong
$ jarsigner -verbose -keystore debug.keystore -signedjar test2.apk tap_unsign1.apk timdong
Enter Passphrase for keystore:
adding: META-INF/MANIFEST.MF
adding: META-INF/ANDROIDD.SF
adding: META-INF/ANDROIDD.RSA
signing: res/drawable/ic_launcher.png
signing: res/layout/main.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: classes.dex