MD五、SHA1和android apk簽名雜談

 這一段是原創,說得不對的地方還請支出(:
       首先要分清楚MD(Message Digest 信息摘要)5(第五代)和SHA1(Secure  Hash  Algorithm 安全哈希算法)並非加密算法,應該歸類爲HASH(哈希)算法或者稱之爲摘要算法(Digest Algorithm),即將無限制長度的字符串轉換成固定長度(MD5是16個字符16*8=128bits,SHA1是20個字節=160bits 20*8bits的長度)。獲得的是摘要,輸入是無限制的字符。
       雖說如今有碰撞算法能夠找到兩個字符使用MD5生成爲同樣的MD5摘要字符,可是並不能說MD5是可逆的
即使是彩虹表也只是相似一個大數據庫,在裏面找相同的罷了。由於兩個不一樣的字符串通過MD5算法以後,有可能生成相同的MD5或者SHA1值。這就像是X+Y=1024,X、Y的組合有許多種,並不能100%準確的指出,XY究竟是兩個什麼值。
       可是MD5和SHA1並非加密算法。沒有所謂的公鑰私鑰。而常見的加密算法有RSA,它屬因而非對稱的加密算法。公鑰位於客戶端,私鑰位於服務器端。私鑰是隻有加密者才能擁有的。須要嚴加保護。【一個公鑰對應一個私鑰。】(有待考證)。通常來講生成私鑰是須要用戶自定義密碼的,例如java中進行私鑰生成的過程當中,須要開發者自行生成私鑰。公鑰可以正確的解密出加密前的內容。

下面一段是轉載的,可是苦於找不到出處,若是侵犯了版權,請聯繫我,立馬刪除        


SHA1即安全哈希算法(Secure Hash Algorithm),用於簽名;RSA是目前最有影響力的公鑰加密算法。
說到這就的提到公鑰和私鑰:公鑰、私鑰分居客戶端和服務器端,分別用於加密和解密。同時,私鑰還用於簽名,公鑰還用於驗證簽名。



畢設作的是Android應用重打包檢測,首先就須要批量檢測Android應用之間簽名是否一致。因此在這裏介紹一下在終端中如何寫腳本或者直接輸入命令批量檢測應用簽名是否一致。

Android應用的發佈形式apk中包含的簽名加密方法除了RSA還有DSA,因此不能只從apk中提取常見的META-INF/CERT.RSA,第一步應該是檢查apk中具體的簽名文件是什麼。
FILE="yourapp.apk"
cert_XSA=`jar tf $FILE | grep SA`
此時獲得的cert_XSA多是META-INF/*.RSA或者META-INF/*.DSA。

接下來從apk中提取具體的簽名文件。
jar xf $FILE $cert_XSA
此時會在當前目錄獲得cert_XSA文件。

而後對於獲得的簽名文件,提取其中籤名的MD5值
keytool -printcert -file $cert_XSA | grep MD5 > "$FILE.certMD5"
這時候yourapp.certMD5這個文件中就保存了yourapp.apkk中的簽名MD5值。

最後比較兩個app的簽名能夠用diff
FILE1="yourapp1.apk"
FILE2="yourapp2.apk"
# ...
# ... 通過上述步驟獲得$FILE1.certMD5和$FILE2.certMD5
# ...
certMD5_diff=`diff $FILE1.certMD5 $FILE2.certMD5`
if [ "$certMD5_diff" = "" ]; then
 echo "$FILE1.certMD5 == $FILE2.certMD5"
fi
輸出yourapp1.apk.certMD5 == yourapp2.apk.certMD5那麼這兩個應用的簽名就一致。


_______________________

獲取apk證書MD5值的方法(JDK的keytool命令)

APK承襲JAVA,證書RSA文件生成方式與JAVA同源,獲取APK證書MD5思路:html

  1. 獲得APK的RSA證書文件
  2. 使用Java工具的keyytool命令獲取

使用該工具準備條件(2選1便可):java

  • 安裝JDK(Java Development Kit)環境便可

爲確保運行,可添加到環境變量或者在cmd窗口中中cd到對應路徑執行。keytool命令對應文件keytool.exe的目錄通常爲C:\Program Files\Java\jre7\bin\keytool.exeandroid

具體步驟git

一、解壓獲得RSA文件

APK以zip文件方式打開,在\META-INF\目錄中存在一個.RSA後綴的文件,通常名爲CERT.RSAgithub

二、使用keytool命令獲取證書信息(包括MD5)

運行以下keytool命令便可:web

keytool -printcert -file CERT.RSA


MD5是一種摘要生成算法,原本不能用於簽名,可是在待簽名數據以後加上一串私密內容,即散列碼,就能夠用於簽名了。可是md5只能作到

防篡改的功能,不能作到防抵賴,由於這串私密內容雙方是都知道的。

DSA和RSA是一種非對稱加密算髮,簽名密鑰分爲公鑰和私鑰。私鑰用於加密,公鑰用於驗證簽名。使用這種算法的簽名即起到防篡改的功能,又起到防抵賴的做用。由於私鑰只有簽名者本身獨有


1,Base64

場景:你想把一組二進制數據表示爲一組可見字符,這樣在某些場合更加利於傳輸,好比在郵件中傳輸。算法

算法http://zh.wikipedia.org/wiki/Base64數據庫

2,DES和RSA

        場景:你想對一組二進制數據進行加密。好比你想保護你的數據不被別人竊取,即便別人有你加密後的二進制數據,但若是沒有密碼,他仍舊不能解開。安全

算法服務器

DES:http://zh.wikipedia.org/wiki/DES 
RSA:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

區別:DES是對稱的加密,也就是說加密和解密的用的是同一個密鑰。RSA用的是非對稱加密,加密用public key,解密用private key。

討論

DES如今能夠被暴力破解,如今通常用AES來替代DES加密。

因爲RSA是非對稱加密,換個說法就是能夠用私鑰加密,用惟一對應的公鑰解密。但這不是公鑰加密(public cryptography)的工做方式。具體參見:

http://stackoverflow.com/questions/1181421/is-possible-to-encrypt-with-private-key-using-net-rsacryptoserviceprovider

所謂的用私鑰加密的真正方式是數字簽名。也就是你對一個二進制流用私鑰進行簽名。在接受端會用公鑰來驗證你的簽名。從而能夠知道來源的真實性和抗抵賴。具體的C#實例能夠參考:https://gist.github.com/3991414

3,SHA1和MD5

場景:你有一組二進制數據,你爲了保證這組二進制數據的完整性,你想爲這組二進制數據生成惟一的數字簽名。

算法

SHA1:http://zh.wikipedia.org/wiki/SHA1 
MD5: http://zh.wikipedia.org/wiki/MD5


你須要瞭解一下不對稱加密的原理,發佈者用私鑰加密,使用者用公鑰解密,所謂簽名就是用私鑰對文件進行加密的過程。簽名固然和文件無關,就比如你給你老婆穿什麼樣的衣服,那仍是你老婆。
packageInfo.signatures不是公鑰,可是能夠經過它獲得公鑰(獲取簽名公鑰

1、Android簽名概述

咱們已經知道的是:Android對每個Apk文件都會進行簽名,在Apk文件安裝時,系統會對其簽名信息進行比對,判斷程序的完整性,從而決定該Apk文件是否能夠安裝,在必定程度上達到安全的目的。

給定一個Apk文件,解壓,能夠看到一個META-INFO文件夾,在該文件夾下有三個文件:分別爲MANIFEST.MFCERT.SFCERT.RSA。這三個文件分別表徵如下含義:

(1)MANIFEST.MF:這是摘要文件。程序遍歷Apk包中的全部文件(entry),對非文件夾非簽名文件的文件,逐個用SHA1生成摘要信息,再用Base64進行編碼。若是你改變了apk包中的文件,那麼在apk安裝校驗時,改變後的文件摘要信息與MANIFEST.MF的檢驗信息不一樣,因而程序就不能成功安裝。

說明:若是攻擊者修改了程序的內容,有從新生成了新的摘要,那麼就能夠經過驗證,因此這是一個很是簡單的驗證。

(2)CERT.SF:這是對摘要的簽名文件。對前一步生成的MANIFEST.MF,使用SHA1-RSA算法,用開發者的私鑰進行簽名。在安裝時只能使用公鑰才能解密它。解密以後,將它與未加密的摘要信息(即,MANIFEST.MF文件)進行對比,若是相符,則代表內容沒有被異常修改。

說明:在這一步,即便開發者修改了程序內容,並生成了新的摘要文件,可是攻擊者沒有開發者的私鑰,因此不能生成正確的簽名文件(CERT.SF)。系統在對程序進行驗證的時候,用開發者公鑰對不正確的簽名文件進行解密,獲得的結果和摘要文件(MANIFEST.MF)對應不起來,因此不能經過檢驗,不能成功安裝文件。

(3)CERT.RSA文件中保存了公鑰、所採用的加密算法等信息。

說明:系統對簽名文件進行解密,所須要的公鑰就是從這個文件裏取出來的。

結論:從上面的總結能夠看出,META-INFO裏面的說那個文件環環相扣,從而保證Android程序的安全性。(只是防止開發者的程序不被攻擊者修改,若是開發者的公私鑰對對攻擊者獲得或者開發者開發出攻擊程序,Android系統都沒法檢測出來。)

參考文章:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html

2、在Eclipse下配置App的簽名信息

對App進行簽名的方式通常有如下幾種:經過Google提供的簽名工具,經過某些開發者開發的簽名工具或者經過Eclipse提供的簽名方法,但通常而言,他們都是在下層調用Google提供的簽名工具,因此簽名的方法都相同。

例如,在Eclipse下面配置簽名信息時,能夠設置開發者信息:

具體參考文章:http://blog.csdn.net/zuolongsnail/article/details/6444197(上圖來源於該文章)

說明:從上圖能夠看出,在Eclipse中,能夠設置開發者的詳細信息。在其餘的簽名工具中,可能會直接調用其餘簽名信息。

值得注意的是,在設置簽名信息的時候,會有以下圖所示的步驟:

請暫且記住這裏有認證指紋信息:MD5和SHA1。因爲這一步驟是在編譯生成Apk文件以前進行的,因此,說明這裏的MD5和SHA1與程序的內容毫無關係,只與開發者的公私鑰對等開發信息有關。

咱們本身設置簽名信息以後開發程序並簽名,獲得的簽名信息通過keytool.exe解析結果以下:

說明:由上圖能夠發現,解析結果中的MD5和SHA1與上面獲得的MD5,SHA1是相同的。

3、同一個公司的不一樣App的簽名有關係嗎?

咱們有一個疑問,許多互聯網大公司會開發許多官方的移動應用,那麼這些應用的簽名信息是否相同呢,他們所用的公私鑰對是否都是同樣的?咱們對Tencent公司的QQ,QQ空間,微信三款產品進行解析,獲得下面的結果和結論。

一、使用keytool.exe

使用Java提供的keytool.exe工具對三款產品的簽名狀況(CERT.RSA文件)進行解析,狀況以下所示。

微信:

QQ:

QQ空間:

說明:從上面的三幅圖能夠看出,雖然同爲Tencent的三款產品,可是他們的全部者信息、簽發人信息等都不盡相同,儘管他們都表示了騰訊公司或者Tencent等信息。由於這是開發者本身設置的,並且微信和QQ屬於不一樣的事業部,辦公地點不一樣,因此他們的簽名信息不一樣也就不足爲奇了。

二、本身寫應用提取

本身寫程序從CERT.RSA提取出公鑰信息和證書中的簽名信息(對開發者信息的簽名,例如姓名,公司,國家等。。。),狀況以下:

因爲都是一些字符,且不少,因此只取開始和結束的幾位比特作一說明:

微信:

公鑰:c05f........5e9f

簽名:3082....1949

QQ:

公鑰:a15e........3695

簽名:3082........2049

QQ空間:

公鑰:82d...........445

簽名:3082........1677

說明:因爲三款App的開發者設置的簽名信息幾乎不一樣,使用的公私鑰對都不一樣,因此這裏取出來的公鑰和簽名信息幾乎不一樣。惟一相同的是三款App的簽名的開始一些比特,多是由於有的信息相同,具體不得而知。

4、同一款App的不一樣版本簽名信息有關係嗎?

爲了說明這個問題,咱們對QQ的兩個版本作了檢測,狀況以下:

QQ4.7.0:

公鑰:a15e........3695

簽名:3082........2049

QQ4.6.2:

公鑰:a15e........3695

簽名:3082........2049

說明:QQ的兩個不一樣版本,從CERT.RSA文件中取出的公鑰和簽名信息,徹底相同。說明QQ開發團隊始終使用的是一個相同的公私鑰對。固然,他們對於不一樣的版本使用不一樣的公私鑰對也是能夠的,也是可能的。這種可能性發生在他們主動更改公私鑰對的狀況下,也可能發生在他們用不一樣的環境進行簽名的狀況下。

5、能夠修改META-INFO文件夾下的文件嗎?

(1)CERT.RSA,CERT.SF的文件名能夠修改。

咱們把CERT.SF的文件名改爲CERT1.SF,把CERT.RSA的文件名改爲CERT1.RSA,原來的Apk文件能夠被成功安裝。

說明:Android系統在檢測的時候,不會必定要找到CERT這種文件名,是按照文件類型來檢測的。可是,若是.RSA文件與.SF文件的名字不一樣,那麼就不能成功安裝。

(2)添加本身的CERT.SF和CERT.RSA文件到META-INFO文件夾下面,不能成功。

說明:在(1)的基礎上,咱們執行(2)操做,不能成功安裝,這是由於Android系統找不到摘要文件與(2)中添加上的兩個文件進行對應。

6、不一樣的簽名應用,獲得的結果可能不一樣。

用Eclipse簽名的Apk文件,解析CERT.RSA文件以後獲得的結果以下:

用Dodo Apktools簽名後的Apk文件解析以後結果以下:

說明:用Dodo簽名的解析文件多了後面的擴展部分,但整體內容不變。

7、應用商店用什麼方式檢測官方版?

豌豆莢推出的洗白白功能很受歡迎,那麼他們是如何辨別App的是不是官方出品的呢?

根據蒐集到的資料,他們CEO說是這樣實現的:將商店裏的App與官網上的App簽名作對比

 

搜索結果王俊煜的描述,他們是經過將開發者上傳的應用與官網上的應用的簽名對比是否相同來肯定App是不是官方出品的。從上面的分析



MANIFET.MF:

CERT.MF
相關文章
相關標籤/搜索