基础Android知识Android开发

Android签名认证分析

2017-07-10  本文已影响1493人  SYfarming

**一.Android签名验证流程基础知识及源码解析:****

Android应用程序签名过程分析:
http://blog.csdn.net/roland_sun/article/details/42029019

Android应用程序签名过程源码分析:
http://blog.csdn.net/roland_sun/article/details/42029019

源码涉及到签名的类为:

1.PackageManangerService(代码位于frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

2.PackageParser(代码位于frameworks\base\core\java\android\content\pm\PackageParser.java,编译后存在于framework.jar文件中)

3.StrictJarFile(代码位于libcore\luni\src\main\java\java\util\jar\StrictJarFile.java,编译后存在于core.jar文件中)

4.JarVeirifer(代码位于libcore\luni\src\main\java\java\util\jar\JarVerifier.java文件中,编译后存在于core.jar文件中)

  1. JarUtils(代码位于libcore\luni\src\main\java\org\apache\harmony\security\utils\JarUtils.java文件中,编译后存在于core.jar文件中)

验证过程主要使用*JarUtils中的
JarVeirifer.verifyCertificate
*函数。

Android采用 PKCS7 信封进行装载 X509 证书和签名封装。

PCKS7: http://baike.baidu.com/link?url=yltprCGYD9M_YHrBXSFMfhpfQyWmBlPZF2T5TG2mLGTOi6uyH3e4aBBJJ6ZQCVbUBKwX_Q7VZAcqLQ-O9CY-mK

X509证书:http://baike.baidu.com/view/3579227.htm

在源码libcore/luni/src/main/java/org/apache/harmony/security中有具体的实现

Apk签名流程:

Paste_Image.png

二.证书格式分析
涉及到的两种证书格式:

X509 是证书规范
PKCS7 是消息语法
(常用于数字签名与加密)作用就是电子信封

PKCS7 一般是把证书分成两个文件,一个公钥一个私钥,有PEM和DER两种编码方式。PEM比较多见,就是纯文本的,P7一般是分发公钥用,看到的就是一串可见字符串,扩展名经常是.crt,.cer,.key等。
DER是二进制编码。在Android中使用的DER的编码格式。

查看命令

查看证书指纹.keystores命令

keytool   –list –v –keystore debug.keystore

查看证书指纹.RSA文件命令

keytool –printcert –file CERT.RSA

使用openssl查看.RSA文件

openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text

查看证书指纹后会发现,RSA文件和.keystores,证书指纹相同,MD5,SHA1,SHA256三种指纹均相同。

证书分析:

1.X.509证书格式如下图所示:

Paste_Image.png

• 这里看到证书中并不包含apk签名流程中第三部生成CERT.RSA时对用私钥计算出的签名。所以证书的信息是不会改变的,这也验证了上面所说的RSA中证书指纹和.keystone中的指纹相同的问题

2.对CERT.RSA进行详细解析

明确了上面的问题之后,对CERT.RSA 文件进行详细解析,得到下图:

Paste_Image.png

说明:
(1)首先,我们的通常所说的证书的签名,是生成证书的时候CA对整个证书的所有域签名的得到的,而不是对某一部分签名得到的。整个签名就是上图中部分一的最下面的一段十六进制的内容;

(2)编程中的获取到的内容实质上是就是上图中的部分二,这是一个证书的所有内容;

使用openssl pkcs7  -inform DER -in CERT.RSA  -print_certs 可得到

(3)部分一中的公钥等信息就是从部分二中得来的,可以直接在部分二中找到。

(4)可以猜测,部分一中的其他信息也是从部分二中得来,只不过编码方式不一样,所以显示不同而已。

三.破解方式
二次打包的目的:

可以修改apk内部构造,接口等,最常见的刷广告,接入广告即可,通过二次打包伪造官方APP应用,从而获取利益

Apk所符合被破解的条件

1.Java层通过

getPackageManager().getPackageInfo.signatures

来获取签名信息;
2.Native方法
/DLL/Lua脚本等通过获取Java的context/Activity对象,反射调用getPackageInfo等来获取签名;
3.首先获取apk的路径,定位到META-INF*.RSA文件,获取其中的签名信息;
4.能自动识别apk的加固类型;

破解方式

方式一:substrate框架libhooksig By空道

1.so文件用于hook sign

2.应用于在程序运行时获取当前进程的签名信息而进行的验证;

原理见:http://www.kanxue.com/bbs/showthread.php?p=1265295

方式二:重写继承类packageInfo和PackageManager By小白

1.适用于Java层packageInfo获取签名信息的方式;

2.亦适用于Native/DLL/LUA层反射packageInfo获取签名信息的方式;

3.该种方式可能会使PackageInfo中的versionCode和versionName为NULL,对程序运行有影响的话,需自主填充修复;

方式三:重写继承类,重置Sign信息;

1.适用于Java层packageInfo获取签名信息的方式;

2.亦适用于Native/DLL/LUA层反射packageInfo获取签名信息的方式;

3.该种方式可能会使PackageInfo中的versionCode和versionName为NULL,对程序运行有影响的话,需自主填充修复;

方式四:针对定位到具体RSA文件路径获取签名的验证方式;

1.针对定位到具体RSA文件路径获取签名的验证方式;

2.曾经破解过消消乐_Ver1.27,但是如果程序本身对META-INF签名文件中的MANIFEST.MF进行了校验,此方式无效,那就非签名校验,而是文件校验了;

方式五:hook android 解析的packageparse类中的两个验证方法pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
修改实现方式。

如何加固APP防止APP被二次打包
通过以上信息,我们可以得到的是,证书作为不变的内容放在PKCS7格式的.RSA文件中,我们在RSA文件上验证的也只有证书。

方案一:

通过


Paste_Image.png Paste_Image.png

通过PackageManag对象可以获取APK自身的签名(方法有很多,最后是都通过

context.getPackageManager().getPackageInfo(
                    this.getPackageName(), PackageManager.GET_SIGNATURES).signature获得
signature)。

这里得到的sign为证书的所有数据,对其做摘要算法,例如
MD5可以得到MD5指纹,对比指纹可以进行安全验证。
Java程序都可以使用jni反射在native实现,分解Java代码太累赘,

方案二:调用隐藏类PackageParser.java中的collectCertificates方法,从源头获取cert证书

方案三:使用openssl使用JNI做RSA解析破解难度是相当的大,同样的解析出x.509证书,java解析转换为native解析so文件,但得到的文件比较大1.3M。。。。显然不可取。。(openssl自己百度下吧)

方案四:通过源码解析我们可以知道,apk文件验证是按照zip文件目录形式查找到.RSA文件结尾,我们可以直接去取文件的绝对路径,拿到证书的公钥信息进行验证(但需要引入PKCS7的库)

方案五:由棒棒加固和爱加密做的思路可以知道,自己重新定制摘要算法,在asset
里面重新搞一套验证流程(代码还没搞完)思路就是生成一个定制的CERT,另外开辟一套验证流程,不使用Android固有的签名认证流程。


关注微信公众号 Android历练记 或扫一扫二维码:
让我们一起来搞事情。

Android历练记
上一篇下一篇

猜你喜欢

热点阅读