国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android的APK應(yīng)用簽名機(jī)制以及讀取簽名的方法

2020-04-11 10:45:47
字體:
供稿:網(wǎng)友

發(fā)布過Android應(yīng)用的朋友們應(yīng)該都知道,Android APK的發(fā)布是需要簽名的。簽名機(jī)制在Android應(yīng)用和框架中有著十分重要的作用。例如,Android系統(tǒng)禁止更新安裝簽名不一致的APK;如果應(yīng)用需要使用system權(quán)限,必須保證APK簽名與Framework簽名一致,等等。

什么是簽名
首先我們得知道什么是摘要,摘要是指采用單向Hash函數(shù)對數(shù)據(jù)進(jìn)行計算生成的固定長度的Hash值,摘要算法有Md5,Sha1等,Md5生成的Hash值是128位的數(shù)字,即16個字節(jié),用十六進(jìn)制表示是32個字符,Sha1生成的Hash值是160位的數(shù)字,即20個字節(jié),用十六進(jìn)制表示是40個字符。我們是不能通過摘要推算出用于計算摘要的數(shù)據(jù),如果修改了數(shù)據(jù),那么它的摘要一定會變化(其實這句話并不正確,只是很難正好找到不同的數(shù)據(jù),而他們的摘要值正好相等)。摘要經(jīng)常用于驗證數(shù)據(jù)的完整性,很多下載網(wǎng)站都會列出下載文件的md5值或者sha1值。
摘要和簽名沒有任何關(guān)系,網(wǎng)上常常將摘要和簽名混為一談,這是錯誤的。簽名和數(shù)字簽名是同一個概念,是指信息的發(fā)送者用自己的私鑰對消息摘要加密產(chǎn)生一個字符串,加密算法確保別人無法偽造生成這段字符串,這段數(shù)字串也是對信息的發(fā)送者發(fā)送信息真實性的一個有效證明。其他發(fā)送者用他們的私鑰對同一個消息摘要加密會得到不同的簽名,接收者只有使用發(fā)送者簽名時使用的私鑰對應(yīng)的公鑰解密簽名數(shù)據(jù)才能得到消息摘要,否則得到的不是正確的消息摘要。
數(shù)字簽名是非對稱密鑰加密技術(shù)+數(shù)字摘要技術(shù)的結(jié)合。
數(shù)字簽名技術(shù)是將信息摘要用發(fā)送者的私鑰加密,和原文以及公鑰一起傳送給接收者。接收者只有用發(fā)送者的公鑰才能解密被加密的信息摘要,然后接收者用相同的Hash函數(shù)對收到的原文產(chǎn)生一個信息摘要,與解密的信息摘要做比對。如果相同,則說明收到的信息是完整的,在傳輸過程中沒有被修改;不同則說明信息被修改過,因此數(shù)字簽名能保證信息的完整性。并且由于只有發(fā)送者才有加密摘要的私鑰,所以我們可以確定信息一定是發(fā)送者發(fā)送的。
另外還需要理解一個概念:數(shù)字證書。數(shù)字證書是一個經(jīng)證書授權(quán)中心數(shù)字簽名的包含公鑰及其擁有者信息的文件。數(shù)字證書的格式普遍采用的是X.509V3國際標(biāo)準(zhǔn),一個標(biāo)準(zhǔn)的X.509數(shù)字證書包含以下一些內(nèi)容:證書的版本信息:
1)證書的序列號,每個證書都有一個唯一的證書序列號;
2)證書所使用的簽名算法;
3)證書的發(fā)行機(jī)構(gòu)名稱,命名規(guī)則一般采用X.500格式;
4)證書的有效期,通用的證書一般采用UTC時間格式,它的計時范圍為1950-2049;
5)證書所有人的名稱,命名規(guī)則一般采用X.500格式;
6)證書所有人的公開密鑰;
7)證書發(fā)行者對證書的簽名。
CERT.RSA包含了數(shù)字簽名以及開發(fā)者的數(shù)字證書。CERT.RSA里的數(shù)字簽名是指對CERT.SF的摘要采用私鑰加密后的數(shù)據(jù),Android系統(tǒng)安裝apk時會對CERT.SF計算摘要,然后使用CERT.RSA里的公鑰對CERT.RSA里的數(shù)字簽名解密得到一個摘要,比較這兩個摘要便可知道該apk是否有正確的簽名,也就說如果其他人修改了apk并沒有重新簽名是會被檢查出來的。
需注意Android平臺的證書是自簽名的,也就說不需要權(quán)威機(jī)構(gòu)簽發(fā),數(shù)字證書的發(fā)行機(jī)構(gòu)和所有人是相同的,都是開發(fā)者自己,開發(fā)者生成公私鑰對后不需要提交到權(quán)威機(jī)構(gòu)進(jìn)行校驗。

讀取簽名
某些時候需要獲取某個特定的apk(已安裝或者未安裝)的簽名信息,如程序自檢測,可信賴的第三方檢測(應(yīng)用市場),系統(tǒng)限定安裝 
對此,有兩種實現(xiàn)方法 
可以使用Java自帶的API(主要用到的為JarFile,JarEntry,Certificate)進(jìn)行獲取,還有一種方法是使用系統(tǒng)隱藏的API PackageParser,通過反射來使用對應(yīng)的API. 
但是由于安卓系統(tǒng)的分裂版本過多,并且不同廠商進(jìn)行的修改很多,依賴反射隱藏API的方法并不能保證兼容性和通用性,因此推薦使用JAVA自帶API進(jìn)行獲?。?nbsp; 
  

   /**    * 從APK中讀取簽名    * @param file    * @return    * @throws IOException    */   private static List<String> getSignaturesFromApk(File file) throws IOException {     List<String> signatures=new ArrayList<String>();     JarFile jarFile=new JarFile(file);     try {       JarEntry je=jarFile.getJarEntry("AndroidManifest.xml");       byte[] readBuffer=new byte[8192];       Certificate[] certs=loadCertificates(jarFile, je, readBuffer);       if(certs != null) {         for(Certificate c: certs) {           String sig=toCharsString(c.getEncoded());           signatures.add(sig);         }       }     } catch(Exception ex) {     }     return signatures;   }  /**    * 加載簽名    * @param jarFile    * @param je    * @param readBuffer    * @return    */   private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) {     try {       InputStream is=jarFile.getInputStream(je);       while(is.read(readBuffer, 0, readBuffer.length) != -1) {       }       is.close();       return je != null ? je.getCertificates() : null;     } catch(IOException e) {     }     return null;   }  /**    * 將簽名轉(zhuǎn)成轉(zhuǎn)成可見字符串    * @param sigBytes    * @return    */   private static String toCharsString(byte[] sigBytes) {     byte[] sig=sigBytes;     final int N=sig.length;     final int N2=N * 2;     char[] text=new char[N2];     for(int j=0; j < N; j++) {       byte v=sig[j];       int d=(v >> 4) & 0xf;       text[j * 2]=(char)(d >= 10 ? ('a' + d - 10) : ('0' + d));       d=v & 0xf;       text[j * 2 + 1]=(char)(d >= 10 ? ('a' + d - 10) : ('0' + d));     }     return new String(text);   } 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 绍兴县| 绵竹市| 临湘市| 宜良县| 临夏市| 泸溪县| 安龙县| 辽宁省| 抚顺县| 大田县| 白河县| 太保市| 莫力| 石家庄市| 梧州市| 徐闻县| 濮阳县| 延吉市| 永仁县| 上杭县| 公主岭市| 股票| 石台县| 津南区| 新沂市| 富顺县| 邢台市| 厦门市| 扬州市| 肇州县| 盖州市| 刚察县| 涞源县| 奇台县| 扎赉特旗| 崇礼县| 宁都县| 宾川县| 大洼县| 潢川县| 蕉岭县|