1. 程式人生 > >Android簽名機制---簽名過程

Android簽名機制---簽名過程

iges 工具 恢復 容易 有一個 需要 還要 兩種 別人

大神文章:http://blog.csdn.net/jiangwei0910410003/article/details/50402000

一、知識點

1、數據摘要(數據指紋)、簽名文件,證書文件

2、jarsign工具簽名和signapk工具簽名

3、keystore文件和pk8文件,x509.pem文件的關系

4、如何手動的簽名apk

二、前提

首先來看一下數據摘要,簽名文件,證書文件的知識點

1、數據摘要

這個知識點很好理解,百度百科即可,其實他也是一種算法,就是對一個數據源進行一個算法之後得到一個摘要,也叫作數據指紋,不同的數據源,數據指紋肯定不一樣,就和人一樣。

消息摘要算法(Message Digest Algorithm)是一種能產生特殊輸出格式的算法,其原理是根據一定的運算規則對原始數據進行某種形式的信息提取,被提取出的信息就被稱作原始數據的消息摘要。
著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的變體。
消息摘要的主要特點有:
1)無論輸入的消息有多長,計算出來的消息摘要的長度總是固定的。例如應用MD5算法摘要的消息有128個比特位,用SHA-1算法摘要的消息最終有160比特位的輸出。
2)一般來說(不考慮碰撞的情況下),只要輸入的原始數據不同,對其進行摘要以後產生的消息摘要也必不相同,即使原始數據稍有改變,輸出的消息摘要便完全不同。但是,相同的輸入必會產生相同的輸出。
3)具有不可逆性,即只能進行正向的信息摘要,而無法從摘要中恢復出任何的原始消息。

2、簽名文件和證書

簽名文件和證書是成對出現了,二者不可分離,而且我們後面通過源碼可以看到,這兩個文件的名字也是一樣的,只是後綴名不一樣。

其實數字簽名的概念很簡單。大家知道,要確保可靠通信,必須要解決兩個問題:首先,要確定消息的來源確實是其申明的那個人;其次,要保證信息在傳遞的過程中不被第三方篡改,即使被篡改了,也可以發覺出來。
所謂數字簽名,就是為了解決這兩個問題而產生的,它是對前面提到的非對稱加密技術與數字摘要技術的一個具體的應用。
對於消息的發送者來說,先要生成一對公私鑰對,將公鑰給消息的接收者。
如果消息的發送者有一天想給消息接收者發消息,在發送的信息中,除了要包含原始的消息外,還要加上另外一段消息。這段消息通過如下兩步生成:
1)對要發送的原始消息提取消息摘要;
2)對提取的信息摘要用自己的私鑰加密。
通過這兩步得出的消息,就是所謂的原始信息的數字簽名。
而對於信息的接收者來說,他所收到的信息,將包含兩個部分,一是原始的消息內容,二是附加的那段數字簽名。他將通過以下三步來驗證消息的真偽:
1)對原始消息部分提取消息摘要,註意這裏使用的消息摘要算法要和發送方使用的一致;
2)對附加上的那段數字簽名,使用預先得到的公鑰解密;
3)比較前兩步所得到的兩段消息是否一致。如果一致,則表明消息確實是期望的發送者發的,且內容沒有被篡改過;相反,如果不一致,則表明傳送的過程中一定出了問題,消息不可信。
通過這種所謂的數字簽名技術,確實可以有效解決可靠通信的問題。如果原始消息在傳送的過程中被篡改了,那麽在消息接收者那裏,對被篡改的消息提取的摘要肯定和原始的不一樣。並且,由於篡改者沒有消息發送方的私鑰,即使他可以重新算出被篡改消息的摘要,也不能偽造出數字簽名。
所以,綜上所述,數字簽名其實就是只有信息的發送者才能產生的別人無法偽造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證明。
不知道大家有沒有註意,前面講的這種數字簽名方法,有一個前提,就是消息的接收者必須要事先得到正確的公鑰。如果一開始公鑰就被別人篡改了,那壞人就會被你當成好人,而真正的消息發送者給你發的消息會被你視作無效的。而且,很多時候根本就不具備事先溝通公鑰的信息通道。那麽如何保證公鑰的安全可信呢?這就要靠數字證書來解決了。
所謂數字證書,一般包含以下一些內容:
證書的發布機構(Issuer)
證書的有效期(Validity)
消息發送方的公鑰
證書所有者(Subject)
數字簽名所使用的算法
數字簽名
可以看出,數字證書其實也用到了數字簽名技術。只不過要簽名的內容是消息發送方的公鑰,以及一些其它信息。但與普通數字簽名不同的是,數字證書中簽名者不是隨隨便便一個普通的機構,而是要有一定公信力的機構。這就好像你的大學畢業證書上簽名的一般都是德高望重的校長一樣。一般來說,這些有公信力機構的根證書已經在設備出廠前預先安裝到了你的設備上了。所以,數字證書可以保證數字證書裏的公鑰確實是這個證書的所有者的,或者證書可以用來確認對方的身份。數字證書主要是用來解決公鑰的安全發放問題。
綜上所述,總結一下,數字簽名和簽名驗證的大體流程如下圖所示:

技術分享

3、jarsign和signapk工具

了解到完了簽名中的三個文件的知識點之後,下面繼續來看看Android中簽名的兩個工具:jarsign和signapk

關於這兩個工具開始的時候很容易混淆,感覺他們兩到底有什麽區別嗎?

其實這兩個工具很好理解,jarsign是Java本生自帶的一個工具,他可以對jar進行簽名的。而signapk是後面專門為了Android應用程序apk進行簽名的工具,他們兩的簽名算法沒什麽區別,主要是簽名時使用的文件不一樣,這個就要引出第三個問題了。

4、keystore文件和pk8,x509.pem文件的區別

我們上面了解到了jarsign和signapk兩個工具都可以進行Android中的簽名,那麽他們的區別在於簽名時使用的文件不一樣

jarsign工具簽名時使用的是keystore文件

signapk工具簽名時使用的是pk8,x509.pem文件

三、簽名詳解

簽名後的apk會多出,MANIFEST.MF、xxxx.DSA(dsa是加密算法,不同的加密算法後綴不同)、xxxxxx.sf。

1.把apk中除了以上三種文件都進行一次SHA-1算法,獲取摘要信息後再用base64進行編碼之後寫入MANIFEST.MF文件。

2.xxx.SF做了:

1》計算這個MANIFEST.MF文件的整體SHA1值,再經過BASE64編碼後,記錄在CERT.SF主屬性塊(在文件頭上)的“SHA1-Digest-Manifest”屬性值值下

2》逐條計算MANIFEST.MF文件中每一個塊的SHA1,並經過BASE64編碼後,記錄在CERT.SF中的同名塊中,屬性的名字是“SHA1-Digest

3.xxxxx.DSA是證書如圖:

技術分享

我們看到,這裏會把之前生成的 CERT.SF文件, 用私鑰計算出簽名, 然後將簽名以及包含公鑰信息的數字證書一同寫入 CERT.RSA 中保存。CERT.RSA是一個滿足PKCS7格式的文件。

四、為何要這麽來簽名

上面我們就介紹了簽名apk之後的三個文件的詳細內容,那麽下面來總結一下,Android中為何要用這種方式進行加密簽名,這種方加密是不是最安全的呢?下面我們來分析一下,如果apk文件被篡改後會發生什麽。

首先,如果你改變了apk包中的任何文件,那麽在apk安裝校驗時,改變後的文件摘要信息與MANIFEST.MF的檢驗信息不同,於是驗證失敗,程序就不能成功安裝。
其次,如果你對更改的過的文件相應的算出新的摘要值,然後更改MANIFEST.MF文件裏面對應的屬性值,那麽必定與CERT.SF文件中算出的摘要值不一樣,照樣驗證失敗。
最後,如果你還不死心,繼續計算MANIFEST.MF的摘要值,相應的更改CERT.SF裏面的值,那麽數字簽名值必定與CERT.RSA文件中記錄的不一樣,還是失敗。
那麽能不能繼續偽造數字簽名呢?不可能,因為沒有數字證書對應的私鑰。
所以,如果要重新打包後的應用程序能再Android設備上安裝,必須對其進行重簽名。

從上面的分析可以得出,只要修改了Apk中的任何內容,就必須重新簽名,不然會提示安裝失敗,當然這裏不會分析,後面一篇文章會註重分析為何會提示安裝失敗。

五、知識點梳理

1、數據指紋,簽名文件,證書文件的含義

1》數據指紋就是對一個數據源做SHA/MD5算法,這個值是唯一的

2》簽名文件技術就是:數據指紋+RSA算法

3》證書文件中包含了公鑰信息和其他信息

4》在Android簽名之後,其中SF就是簽名文件,RSA就是證書文件我們可以使用openssl來查看RSA文件中的證書信息和公鑰信息

2、我們了解了Android中的簽名有兩種方式:jarsigner和signapk 這兩種方式的區別是:

1》jarsigner簽名時,需要的是keystore文件,而signapk簽名的時候是pk8,x509.pem文件

2》jarsigner簽名之後的SF和RSA文件名默認是keystore的別名,而signapk簽名之後文件名是固定的:CERT

3》Eclipse中我們在跑Debug程序的時候,默認用的是jarsigner方式簽名的,用的也是系統默認的debug.keystore簽名文件

4》keystore文件和pk8,x509.pem文件之間可以互相轉化

技術分享

Android簽名機制---簽名過程