AndroidV1,V2,V3簽名原理詳解
- 簽名校驗流程
- 不同的簽名版本之間的區別
- V1簽名保護機制
- V2簽名保護機制
- V3簽名保護機制
- 怎樣判斷使用的是哪種簽名
- 參考鏈接:
簽名校驗流程
基礎知識:
1.數字簽名
2.數字證書
3.對稱加密和非對稱加密
背景介紹:
一般開發者會指定使用自己創建的證書,如果沒有指定,則會默認使用系統的證書,該默認的證書存盤在C:\Users\admin.android\debug.keystore,不同的電腦可能安裝不同路徑,一個簽名證書檔案中,是包含一對公私鑰,用私鑰對apk進行簽名,在安裝到android手機時,系統會使用證書中對應簽名私鑰的公鑰來驗證,查看apk是否被更改過,如果沒有則可以安裝在手機上,任何的app store都不允許使用默認的debug.keystore打包的apk發布上去,因為debug.keystore的密碼是默認的,不安全,
一,沒有簽名的APK無法安裝
Android的APK要進行簽名才能夠安裝到手機上,這是因為在安裝的時候系統會進行檢測,平時我們直接點AS里面那個綠色的運行按鈕也能夠直接安裝到手機上,這是因為其實它也進行了簽名,只不過AS自動幫我們做了這個操作有個默認的簽名
(在.android目錄中有個debug.keystore默認的簽名),
二,校驗流程
9.0以上的系統會判斷apk是否使用到V3版本的簽名,如果有,那么按照V3版本簽名校驗方式進行校驗校驗成功直接安裝,校驗失敗拒絕安裝;如果apk不是使用V3簽名,判斷是不是使用V2,如果沒有使用V2那么再判斷是不是使用V1的簽名,
三,進行V3簽名
Android不支持V3版本的簽名,所以在AS里面看不到V3,但是在SDK中有個簽名工具apksigner.jar,只有9.0以上這個簽名工具才能簽V3版本的簽名,
(如果想要簽V3版本的簽名,那么只能自己去使用這個簽名工具在命令列中進行簽名)
接下來詳細介紹的就是不同的簽名版本之間的區別,
不同的簽名版本之間的區別

V1簽名保護機制
保護APK中已有檔案
基于JAR的簽名,在打包后的apk中會多三個檔案:

一.MANIFEST.MF
APK當中的所有檔案都會列出來用Name表示,除此之外每個檔案都有SHA-256簽名摘要記錄
簽名摘要記錄:校驗碼對我們的資料內容進行驗證,防止別人會修改你的檔案,如果檔案改動那么對應的檢驗碼就會不一致

二.CERT.SF
這里面存放的和上面MANIFEST.MF的內容一樣,只不過多了一個檔案就是MANIFEST.MF檔案,并對它進行了和其他檔案一樣的操作:生成校驗碼,
目的:上面說過修改了檔案后,如果只是和之前檔案的校驗碼對比是可以檢測到修改的,但是如果我把檔案和校驗碼都進行修改,那么他就檢測不出來,這樣的安全性就太低了,所以我們把上面的MANIFEST.MF檔案也給他進行一次校驗,
但是如果你把SF檔案和校驗碼也改了呢?接下來看最后一個檔案CERT.RSA
三.CERT.RSA
在簽名的時候會給一個證書,里面有公鑰和私鑰;
這個RSA檔案使用私鑰計算SF檔案的數字簽名+包含公鑰的證書資訊保存到RSA檔案中,
第三層防護:理論上沒有私鑰是無法偽裝數字簽名的,
總結:
RSA檔案保護SF檔案,SF檔案保護MF檔案,MF檔案保護apk中已有的所有檔案
注意:V1簽名保護的是APK中已有檔案不被修改,但是新加的檔案并不會受影響,
下面我們來分析一下,如果apk檔案被篡改后會發生什么,
首先,如果你改變了apk包中的任何檔案,那么在apk安裝校驗時,改變后的檔案摘要資訊與MANIFEST.MF的檢驗資訊不同,于是驗證失敗,程式就不能成功安裝,
其次,如果你對更改的過的檔案相應的算出新的摘要值,然后更改MANIFEST.MF檔案里面對應的屬性值,那么必定與CERT.SF檔案中算出的摘要值不一樣,照樣驗證失敗,
最后,如果你還不死心,繼續計算MANIFEST.MF的摘要值,相應的更改CERT.SF里面的值,那么數字簽名值必定與CERT.RSA檔案中記錄的不一樣,還是失敗,
那么能不能繼續偽造數字簽名呢?不可能,因為沒有數字證書對應的私鑰,
所以,如果要重新打包后的應用程式能再Android設備上安裝,必須對其進行重簽名,
從上面的分析可以得出,只要修改了Apk中的任何內容,就必須重新簽名,不然會提示安裝失敗,
V2簽名保護機制
保護的是整個APK的位元組資料
原理:apk檔案本身就是一個zip檔案,按照ZIP檔案格式插入APK Signing Block分塊去記錄簽名資訊

APK Signing Block格式:

size of block: APK分塊總長度-8
id-value paris: id與value資料總長度
id:id資料
value:value資料
size of block:與第一個欄位相同
magic:魔數(標記檔案格式,目的為了快速識別檔案格式)
舉例:
假如APK簽名分塊資料總長度為108
size of block:100(108-8)
id-value paris:X(id和value總長度)
id:(4個位元組)
value:簽名資訊(X-4)
size of block:100(108-8)
magic:ZIP檔案的魔數
其中可以有多個id-value paris,id和value
那么前面說過V2簽名保護的是整個ZIP檔案的位元組資料,那么具體是保護哪些呢:

可以看到保護的是1,3,4部分和剛才圖里面的APK中V2簽名存盤的其中一個ID值對,但是"剛剛說了可以有多個id-value paris,id和value值對,所以我們可以添加這些東西而且不會影響簽名機制"
V3簽名保護機制
V3簽名和V2簽名類似,區別:
一,V3簽名多了一個判斷機制:“APK簽名資料塊大小必須是4096的倍數”
二,V3簽名分塊采用V2相同的簽名分塊格式,只不過改了V2簽名分塊中的那個ID
三,增添了有關受支持的SDK版本和prof-of-rotation結構的資訊
怎樣判斷使用的是哪種簽名
V1直接看APK的目錄就可以分辨
另外兩個涉及到了EOCD格式中有一個值代表Central Directory到Contents of Zip Entries的位移,
這里就用圖去表示了,,

由此也可以得出:偏移量-APK簽名分塊長度=簽名分塊從第幾個位元組開始
偏移量:上面提到過在EOCD格式中存盤著
APK簽名分塊長度:偏移量-16個位元組(magic魔數)-8個位元組(size of block)
參考鏈接:
https://www.2cto.com/kf/201512/455388.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/304915.html
標籤:java
