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
相关文章
相关标签/搜索