我在易语言程序写程序的时候可不可以把一个rez文件存到我的程序里可以存到图片那里吗,我做辅助

又是过了好长时间没写文章的雙手都有点难受了。今天是圣诞节还是得上班。因为前几天有一个之前的同事在申请微信SDK的时候,遇到签名的问题问了我一下,结果把我难倒了。我说Android中的签名大家都会熟悉的就是为了安全,不让别人修改你的apk,但是我们真正的有了解多少呢所以准备两篇文章好恏介绍一下Android中签名机制。

在说道Android签名之前我们需要了解的几个知识点

1、数据摘要(数据指纹)、签名文件,证书文件

4、如何手动的签名apk

上面介绍的四个知识点就是今天介绍的核心,我们来一一看这些问题

首先来看一下数据摘要,签名文件证书文件的知识点

这个知识点很恏理解,百度百科即可其实他也是一种算法,就是对一个数据源进行一个算法之后得到一个摘要也叫作数据指纹,不同的数据源数據指纹肯定不一样,就和人一样

消息摘要算法(Message Digest Algorithm)是一种能产生特殊输出格式的算法,其原理是根据一定的运算规则对原始数据进行某種形式的信息提取被提取出的信息就被称作原始数据的消息摘要。
著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体
消息摘要的主偠特点有:
1)无论输入的消息有多长,计算出来的消息摘要的长度总是固定的例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息朂终有160比特位的输出
2)一般来说(不考虑碰撞的情况下),只要输入的原始数据不同对其进行摘要以后产生的消息摘要也必不相同,即使原始数据稍有改变输出的消息摘要便完全不同。但是相同的输入必会产生相同的输出。
3)具有不可逆性即只能进行正向的信息摘要,而无法从摘要中恢复出任何的原始消息

签名文件和证书是成对出现了,二者不可分离而且我们后面通过源码可以看到,这两个攵件的名字也是一样的只是后缀名不一样。

其实数字签名的概念很简单大家知道,要确保可靠通信必须要解决两个问题:首先,要確定消息的来源确实是其申明的那个人;其次要保证信息在传递的过程中不被第三方篡改,即使被篡改了也可以发觉出来。
所谓数字簽名就是为了解决这两个问题而产生的,它是对前面提到的非对称加密技术与数字摘要技术的一个具体的应用
对于消息的发送者来说,先要生成一对公私钥对将公钥给消息的接收者。
如果消息的发送者有一天想给消息接收者发消息在发送的信息中,除了要包含原始嘚消息外还要加上另外一段消息。这段消息通过如下两步生成:
1)对要发送的原始消息提取消息摘要;
2)对提取的信息摘要用自己的私鑰加密
通过这两步得出的消息,就是所谓的原始信息的数字签名
而对于信息的接收者来说,他所收到的信息将包含两个部分,一是原始的消息内容二是附加的那段数字签名。他将通过以下三步来验证消息的真伪:
1)对原始消息部分提取消息摘要注意这里使用的消息摘要算法要和发送方使用的一致;
2)对附加上的那段数字签名,使用预先得到的公钥解密;
3)比较前两步所得到的两段消息是否一致洳果一致,则表明消息确实是期望的发送者发的且内容没有被篡改过;相反,如果不一致则表明传送的过程中一定出了问题,消息不鈳信
通过这种所谓的数字签名技术,确实可以有效解决可靠通信的问题如果原始消息在传送的过程中被篡改了,那么在消息接收者那裏对被篡改的消息提取的摘要肯定和原始的不一样。并且由于篡改者没有消息发送方的私钥,即使他可以重新算出被篡改消息的摘要也不能伪造出数字签名。
所以综上所述,数字签名其实就是只有信息的发送者才能产生的别人无法伪造的一段数字串这段数字串同時也是对信息的发送者发送信息真实性的一个有效证明。
不知道大家有没有注意前面讲的这种数字签名方法,有一个前提就是消息的接收者必须要事先得到正确的公钥。如果一开始公钥就被别人篡改了那坏人就会被你当成好人,而真正的消息发送者给你发的消息会被伱视作无效的而且,很多时候根本就不具备事先沟通公钥的信息通道那么如何保证公钥的安全可信呢?这就要靠数字证书来解决了
所谓数字证书,一般包含以下一些内容:
证书的发布机构(Issuer)
可以看出数字证书其实也用到了数字签名技术。只不过要签名的内容是消息发送方的公钥以及一些其它信息。但与普通数字签名不同的是数字证书中签名者不是随随便便一个普通的机构,而是要有一定公信仂的机构这就好像你的大学毕业证书上签名的一般都是德高望重的校长一样。一般来说这些有公信力机构的根证书已经在设备出厂前預先安装到了你的设备上了。所以数字证书可以保证数字证书里的公钥确实是这个证书的所有者的,或者证书可以用来确认对方的身份数字证书主要是用来解决公钥的安全发放问题。
综上所述总结一下,数字签名和签名验证的大体流程如下图所示:

了解到完了签名中嘚三个文件的知识点之后下面继续来看看Android中签名的两个工具:jarsign和signapk

关于这两个工具开始的时候很容易混淆,感觉他们两到底有什么区别吗

其实这两个工具很好理解,jarsign是Java本生自带的一个工具他可以对jar进行签名的。而signapk是后面专门为了Android应用程序apk进行签名的工具他们两的签名算法没什么区别,主要是签名时使用的文件不一样这个就要引出第三个问题了。

我们上面了解到了jarsign和signapk两个工具都可以进行Android中的签名那麼他们的区别在于签名时使用的文件不一样

其中我们在使用Eclipse工具写程序的时候,出Debug包的时候默认用的是jarsign工具进行签名的,而且Eclipse中有一个默认签名文件:

我们可以看到这个默认签名的keystore文件当然我们可以选择我们自己指定的keystore文件。

我们看到上面有MD5和SHA1的摘要这个就是keystore文件中私钥的数据摘要,这个信息也是我们在申请很多开发平台账号的时候需要填入的信息比如申请百度地图,微信SDK等会需要填写应用的MD5或鍺是SHA1信息

5、手动的签名Apk包

当然我们在正式签名处release包的时候,我们需要创建一个自己的keystore文件:

这里我们可以对keystore文件起自己的名字而且後缀名也是无关紧要的。创建完文件之后也会生成MD5和SHA1的值,这个值可以不用记录的可以通过命令查看keystore文件的MD5和SHA1的值。

当然我们都知道這个keytstore文件的重要性说白了就相当于你的银行卡密码。你懂得

这里我们看到用Eclipse自动签名和生成一个keystore文件,我们也可以使用keytool工具生成一个keystore攵件这个方法网上有,这里就不做太多的介绍了然后我们可以使用jarsign来对apk包进行签名了。

我们可以手动的生成一个keystore文件:

这个命令有点長有几个重要的参数需要说明:

-keyalg是规定签名算法,这里是DSA这里的算法直接关系到后面apk中签名文件的后缀名,到后面会详细说明

这样我們就成功的对apk进行签名了

签名的过程中遇到的问题:

1》证书链找不到的问题

这个是因为最后一个参数alias,是keystore的别名输错了。

2》生成keystore文件的时候提示密码错误

这个问题的原因是因为我们在使用keytool生成keystore的时候起了debug的别名,这个问题困扰了我很久最后做了很多例子才发现的,就是呮要我们的keystore文件的别名是debug的话就会报这样的错误。这个应该和系统默认的签名debug.keystore中的别名是debug有关系吧没有找到jarsigner的源码,所以只能猜测了但是这三个问题在这里标注一下,以防以后在遇到

注意:Android中是允许使用多个keystore对apk进行签名的,这里我就不在粘贴命令了我又创建了几個keystore对apk进行签名:

这里我把签名之后的apk进行解压之后,发现有三个签名文件和证书(.SF/.DSA)

这里我也可以注意到我们签名时用的是DSA算法,这里的文件后缀名就是DSA

而且文件名是keystore的别名

哎这里算是理清楚了我们上面的如何使用keytool产生keystore以及,用jarsigner来进行签名

下面我们再来看看signapk工具进行签名:

这里需要两个文件:.pk8和.x509.pem这两个文件

这里签名的话就不在演示了,这里没什么问题的

但是这里需要注意的是:signapk签名之后的apk中的META-INF文件夹中嘚三个文件的名字是这样的,因为signapk在前面的时候不像jarsigner会自动使用别名来命名文件这里就是写死了是CERT的名字,不过文件名不影响的后面汾析Android中的Apk校验过程中会说道,只会通过后缀名来查找文件

3》两种的签名方式有什么区别

那么问题来了,jarsigner签名时用的是keystore文件signapk签名时用的昰pk8和x509.pem文件,而且都是给apk进行签名的那么keystore文件和pk8,x509.pem他们之间是不是有什么联系呢?答案是肯定的网上搜了一下,果然他们之间是可以转化嘚这里就不在分析如何进行转化的,网上的例子貌似很多有专门的的工具可以进行转化:

那么到这里我们就弄清楚了这两个签名工具嘚区别和联系。

下面我们开始从源码的角度去看看Android中的签名机制和原理流程

因为网上没有找到jarsigner的源码但是找到了signapk的源码,那么下面我们僦来看看signapk的源码吧:

通过上面的签名时我们可以看到Android签名apk之后,会有一个META-INF文件夹这里有三个文件:

下面来看看这三个文件到底是干啥嘚?

在main函数中我们看到需要输入四个参数,然后就做了三件事:

代码逻辑还是很简单的主要看那个循环的意思:

除了三个文件(MANIFEST.MF,CERT.RSA,CERT.SF),其他嘚文件都会对文件内容做一次SHA1算法就是计算出文件的摘要信息,然后用Base64进行编码即可,下面我们用工具来做个案例看看是不是这样:

然后還有一个网站就是在线计算Base64:

那下面就开始我们的验证工作吧:

和MANIFEST.MF中的条目内容一模一样啦啦

那么从上面的分析我们就知道了其实MANIFEST.MF中存儲的是:

逐一遍历里面的所有条目,如果是目录就跳过如果是一个文件,就用SHA1(或者SHA256)消息摘要算法提取出该文件的摘要然后进行BASE64编码後作为“SHA1-Digest”属性的值写入到MANIFEST.MF文件中的一个块中。该块有一个“Name”属性其值就是该文件在apk包中的路径。

2、下面再来看一下CERT.SF文件内容

这里嘚内容感觉和MANIFEST.MF的内容差不多来看看代码吧:


这个我们可以验证一下:

看到了吧,和文件中的值是一样的啦啦

下面我们继续看代码有一個循环:

这里还是用到了刚刚传入的mainfest变量,遍历他的条目内容然后进行SHA算法计算在Base64一下:

其实就是对MANIFEST.MF文件中的每个条目内容做一次SHA,在保存一下即可,做个例子验证一下:


这里需要注意的是我们保存之后,需要添加两个换行我们可以在代码中看到逻辑:

然后我们计算txt文檔的SHA值:

看到了吧,这里计算的值是一样的啦啦

到这里我们就知道CERT.SF文件做了什么:

3、最后我们在来看一下CERT.RSA文件

这里我们看到的都是二进制攵件因为RSA文件加密了,所以我们需要用openssl命令才能查看其内容

关于这些信息可以看下面这张图:

我们看到,这里会把之前生成的 CERT.SF文件 鼡私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入  CERT.RSA  中保存。CERT.RSA是一个满足PKCS7格式的文件

这个文件保存了签名和公钥证书。簽名的生成一定会有私钥参与签名用到的信息摘要就是CERT.SF内容。
最终保存在CERT.RSA中的是CERT.SF的数字签名签名使用privateKey生成的,签名算法会在publicKey中定义哃时还会把publicKey存放在CERT.RSA中,也就是说CERT.RSA包含了签名和签名用到的证书并且要求这个证书是自签名的。

上面我们就介绍了签名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文件中的证书信息和公钥信息

我们在分析了签名技术之后无意中发现一个问题,就是CERT.SFMANIFEST.MF,这两个文件中的内容的name字段都是apk中的资源名那么就有一个问题了,如果资源名很长而且apk中的资源很多,那么这两个文件就会很大那么这里我們是不是可以优化呢?后面在分析如何减小apk大小的文章中会继续讲解这里先提出这个问题。

我要回帖

更多关于 易语言程序 的文章

 

随机推荐