返回介绍

12.1 基本概念

发布于 2024-10-10 22:32:18 字数 6308 浏览 0 评论 0 收藏 0

在讲 Android 签名之前,需要了解几个知识点:

·数据摘要(数据指纹)、签名文件、证书文件。

·jarsign 工具和 signapk 工具。

·keystore 文件和 pk8 文件、x509.pem 文件的关系。

·如何手动签名 apk。

1.数据摘要

数据摘要其实也是一种算法,就是对一个数据源进行一个算法操作之后得到一个摘要,也叫作数据指纹,不同的数据源,数据指纹肯定不一样,就和人一样。

消息摘要算法(Message Digest Algorithm)是一种能产生特殊输出格式的算法,其原理是根据一定的运算规则对原始数据进行某种形式的信息提取,提取出的信息就称为原始数据的数据摘要。

著名的数据摘要算法有 RSA 公司的 MD5 算法和 SHA-1 算法及其大量的变体。

数据摘要的主要特点有:

·无论输入的消息有多长,计算出来的数据摘要的长度总是固定的。例如应用 MD5 算法摘要的消息有 128 位,用 SHA-1 算法摘要的消息最终有 160 位。

·一般来说(不考虑碰撞的情况下),只要输入的原始数据不同,对其进行摘要以后产生的数据摘要也必不相同,即使原始数据稍有改变,输出的数据摘要便完全不同。但是,相同的输入必会产生相同的输出。

·具有不可逆性,即只能进行正向的数据摘要,而无法从摘要中恢复出任何的原始消息。

2.签名文件和证书文件

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

数字签名要确保可靠通信,必须要解决两个问题:首先,要确定消息的来源确实是其申明的那个人;其次,要保证信息在传递的过程中不被第三方篡改,即使被篡改了,也可以发觉出来。

所谓数字签名,就是为了解决这两个问题而产生的,它是对前面提到的非对称加密技术与数字摘要技术的一个具体的应用。

对于消息的发送者来说,先要生成一对公私钥对,将公钥给消息的接收者。

如果消息的发送者有一天想给消息接收者发消息,在发送的信息中,除了要包含原始的消息外,还要加上另外一段消息。这段消息通过如下两步生成:

1)对要发送的原始消息提取数据摘要。

2)对提取的数据摘要用自己的私钥加密。

通过这两步得出的消息,就是所谓的原始信息的数字签名。

而对于信息的接收者来说,他所收到的信息,将包含两个部分,一是原始的消息内容,二是附加的那段数字签名。他将通过以下三步来验证消息的真伪:

1)对原始消息部分提取数据摘要,注意这里使用的数据摘要算法要和发送方使用的一致。

2)对附加上的那段数字签名,使用预先得到的公钥解密。

3)比较前两步所得到的两段消息是否一致。如果一致,则表明消息确实是期望的发送者发的,且内容没有被篡改过;相反,如果不一致,则表明传送的过程中一定出了问题,消息不可信。

这种数字签名技术确实可以有效解决可靠通信的问题。如果原始消息在传送的过程中被篡改了,那么在消息接收者那里,对被篡改的消息提取的摘要肯定和原始的不一样。并且,由于篡改者没有消息发送方的私钥,即使他可以重新算出被篡改消息的摘要,也不能伪造出数字签名。

综上所述,数字签名其实就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。

不知道大家有没有注意,前面讲的这种数字签名方法,有一个前提,就是消息的接收者必须要事先得到正确的公钥。如果一开始公钥就被别人篡改了,那坏人就会被你当成好人,而真正的消息发送者给你发的消息会被你视作无效的。而且,很多时候根本就不具备事先沟通公钥的信息通道。那么如何保证公钥的安全可信呢?这就要靠数字证书来解决了。

数字证书一般包含以下一些内容:

·证书的发布机构(Issuer)

·证书的有效期(Validity)

·消息发送方的公钥

·证书所有者(Subject)

·数字签名所使用的算法

·数字签名

可以看出,数字证书其实也用到了数字签名技术。只不过要签名的内容是消息发送方的公钥,以及一些其他信息。但与普通数字签名不同的是,数字证书中签名者不是随随便便一个普通的机构,而是要有一定公信力的机构。这就好像你的大学毕业证书上签名的一般都是德高望重的校长一样。一般来说,这些有公信力机构的根证书已经在设备出厂前预先安装到了你的设备上了。所以,数字证书可以保证数字证书里的公钥确实是这个证书的所有者的,或者证书可以用来确认对方的身份。数字证书主要是用来解决公钥的安全发放问题。

综上所述,总结一下,数字签名和签名验证的大体流程如图 12-1 所示。

图 12-1 签名过程

3.jarsign 和 signapk 工具

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

开始使用这两个工具很容易混淆,它们到底有什么区别吗?其实这两个工具很好理解,jarsign 是 jdk 本身自带的一个工具,它可以对 jar 进行签名。而 signapk 是后面专门为了 Android 应用程序 apk 进行签名的工具,它们的签名算法没什么区别,主要是签名时使用的文件不一样。

4.keystore 文件和 pk8、x509.pem 文件的区别

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

·jarsign 工具签名时使用的是 keystore 文件。

·signapk 工具签名时使用的是 pk8、x509.pem 文件。

在使用 Eclipse 工具编写程序出 debug 包的时候,默认用的是 jarsign 工具进行签名的,而且 Eclipse 中有一个默认签名文件,如图 12-2 所示。

图 12-2 Eclipse 中默认签名文件

有默认签名的 keystore 文件,当然也可以选择指定的 keystore 文件。看到上面有 MD5 和 SHA1 的摘要,这个就是 keystore 文件中私钥的数据摘要,这个信息也是在申请很多开发平台账号的时候需要填入的信息,比如申请百度地图、微信 SDK 等,会需要填写应用的 MD5 或者 SHA1 信息。

5.手动签名 apk 包

(1)使用 keytool 和 jarsigner 来进行签名

当然,在正式签名处 release 包的时候,需要创建一个自己的 keystore 文件,如图 12-3 和图 12-4 所示。

图 12-3 导出签名 apk

图 12-4 导出签名 apk

这里可以对 keystore 文件起自己的名字,而且后缀名也是无关紧要的。创建完文件之后,也会生成 MD5 和 SHA1 值,这个值可以不用记录的,可以通过命令查看 keystore 文件的 MD5 和 SHA1 的值:keytool-list-keystore debug.keystore,如下所示:

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

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

·-alias 是定义别名,这里是 debug。

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

再用 jarsigner 工具进行签名,如下所示:

这样就成功地对 apk 进行签名了。

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

1)证书链找不到的问题,如下所示:

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

2)生成 keystore 文件的时候提示密码错误,如下所示:

这个原因是因为在当前目录已经有 debug.ketystore 了,再生成一个 debug.keystore 的话,就会报错。

3)找不到别名的问题,如下所示:

这个问题的原因是使用 keytool 生成 keystore 的时候,起了 debug 的别名,这个问题困扰了我很久,最后做了很多例子才发现的,只要 keystore 文件的别名是 debug 的话,就会报这样的错误。这个应该和系统默认的签名 debug.keystore 中的别名是 debug 有关系。

注意:Android 中是允许使用多个 keystore 对 apk 进行签名的,这里就不再粘贴命令了,创建了几个 keystore 对 apk 进行签名,如图 12-5 所示。

图 12-5 签名文件目录

这里把签名之后的 apk 进行解压之后,发现有三个签名文件和证书(.SF/.DSA)。也可以注意到,签名时用的是 DSA 算法,这里的文件后缀名就是 DSA,而且文件名是 keystore 的别名,这里算是理清了如何使用 keytool 产生 keystore,以及用 jarsigner 来进行签名。

(2)用 signapk 来进行签名

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

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

·pk8 是私钥文件。

·x509.pem 是含有公钥的文件。

需要注意的是:signapk 签名之后的 apk,META-INF 文件夹中的三个文件的名字,如图 12-6 所示。

图 12-6 签名文件

因为 signapk 在前面的时候不像 jarsigner 会自动使用别名来命名文件,就是写死了是 CERT 的名字,不过文件名不影响的,后面分析 Android 中的 apk 校验过程中会说道,只会通过后缀名来查找文件。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文