Android签名原理
来源:互联网 发布:微软keeper是什么软件 编辑:程序博客网 时间:2024/06/04 19:09
一、如何对一个APK签名?
网上资料比较多,找了一个比较好的:
http://xlover.iteye.com/blog/1111560
简单来说,步骤为:
1、生成签名文件key.keystore,并指定签名文件的密码:
jarsigner -verbose -keystore key.keystore -signedjar notepad_signed.apk notepad.apk key.keystore
2、用签名文件key.keystore对APK进行签名:
jarsigner -verbose -keystorekey.keystore -signedjar notepad_signed.apk notepad.apk key.keystore
二、签名的作用是什么?
这里需要补一下信息安全方面的知识,如下,数字签名的作用:
http://www.docin.com/p-99435359.html
因此,衍生出两个Android签名最重要的作用:
1、确认你的APK没有被人恶意篡改;(数字签名的作用)PS:脑补一下,QQ里面被人恶意篡改,然后你在不知情的情况下下载到
2、通过对比你的签名文件,保证在覆盖安装时,你的APP不会被其他人覆盖;(衍生作用) PS:你应该不希望自己的APP被其他人覆盖吧,除了你自己
4、签名是如何起作用的?
目前主流的签名算法,有RSA、DES等等,都是基于一些公认的数学理论;(比如RSA是基于大数分解)
简单来说,签名步骤如下:
1、使用私钥R,对数据D进行计算,得出结果S;
2、将公钥P,公布给其他人,其他任何使用P,能对数据D,结果S,进行验证。
3、如果P+S+D=验证通过,那么其他人认为数据D没有被篡改;
对应到Android中,就是(以下以RSA算法签名为案例):
私钥R:存储在key.keystore中;
公钥P:存储在key.keystore中(我自己总要存一份吧),对外存储在META-INF\CERT.RSA中(任何人都可以拿到);
数据D:APK中的每个文件(记录在META-INF\MANIFEST.MF中);
结果S:存储在META-INF\CERT.SF中;
反过来,已经明白APK中key.keystore文件的实际意义,以及META-INF以及各个文件的作用,详情如下:
key.keystore:存储私钥+公钥,用户可以通过密码提取出来;
CERT.RSA:对外暴露的公钥
MANIFEST.MF:记录APK每个文件的MD5
CERT.SF:保存签名结果
系统验证只需要保证(CERT.RSA、MANIFEST.MF、CERT.SF)能满足某一数学公式即可
附上RSA算法原理,有兴趣可以看一下签名过程以及验证过程:
http://blog.csdn.net/sunmenggmail/article/details/11994013
三、MANIFEST.MF 解析
上面已经说明了MANIFEST.MF 作用,现在详解其格式;
随便打开一个APK文件,MANIFEST.MF 格式都是:
Manifest-Version: 1.0
Created-By: 1.6.0_24 (Sun Microsystems Inc.)
Name:XXXXX
SHA1-Digest:XXXXXX
..........
..........
..........
很好理解,Name表示单个文件路径,SHA1-Digest表示MD5信息。MANIFEST.MF 存储所有APK文件的SHA1值
四、通常说的APK签名是什么?
签名指的是:android.content.pm.PackageInfo中Signature[] signatures对象
通常来说,为了方便数据计算,需要对其signatures[0] or 1 计算MD5值,转换成为string对象:
try { PackageInfo packageInfo = getPackageManager() .getPackageInfo(packageName, PackageManager.GET_SIGNATURES); String signMd5 = MD5.toMD5(packageInfo.signatures[packageInfo.signatures.length - 1].toCharsString()); Log.d("Sign",signMd5); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }
同理,在JAVA在读取签名:
/** * 获取android包里面的所有证书MD5 * @param apkFile 包文件 * @return */ public static String getSigMd5(File apkFile) { //解压APK文件,;略 String unPackFile = unpack(apkFile); //针对使用RSA算法签名的APK,获取./META-INF/*.RSA文件 File cerFile = getRSAFile(unPackFile); //针对使用DSA算法签名的APK,获取./META-INF/*.DSA文件 if (cerFile == null ) cerFile = getDSAFile(unPackFile); FileInputStream input = null; try { input = new FileInputStream(cerFile); PKCS7 pkcs7 = new PKCS7(input); Certificate[] certs = pkcs7.getCertificates(); String eggPainSign = (new String(BytetoChars(certs[certs.length - 1].getEncoded()))); String eggPainMd5 = MD5.toMD5(eggPainSign.getBytes()); return eggPainMd5; } catch (Exception e) { e.printStackTrace(); } finally { if (input != null) { try { input.close(); } catch (IOException e) { } } } return null; }
原理是:找到METE-INF下存储签名的文件(可能是RSA或者RSA结尾),生成Certificate[]对象,取起MD5即可;同时可以发现,Signature对象其实就是在Certificate基础上做了一层封装,其中BytetoChars方法如下:
/** * @param mSignature * @return */ private static char[] BytetoChars(byte[] mSignature) { byte[] sig = mSignature; 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 text; }
- Android签名原理
- android APK签名原理
- Android apk 签名原理
- Android apk签名原理
- Android 应用 签名原理
- Android签名机制原理
- Android的Apk签名原理
- Android签名与认证原理
- Android签名验证原理解析
- Android签名与认证原理
- Android 签名机制:Key的产生方法和签名原理
- Android APK签名原理及方法
- Android第二个绕过签名认证漏洞原理
- android签名
- android签名
- android签名
- Android签名
- android签名
- Discount Louis Vuitton Bags 1P6C8
- iOS用ASIHTTPRequest框架实现多张图片上传
- Louis Vuitton Outlet Belts QdPr0
- 真正的程序员,请你站出来
- 我的第一周cpp课程
- Android签名原理
- 【LeetCode】Divide Two Integers
- 第七周项目二并联电路
- hdu-4539 郑厂长系列故事――排兵布阵(状态压缩)
- GTK在Linux下的安装
- 湖南省第七届大学生计算机程序设计竞赛 多连块拼图 (模拟)
- 连接mysql数据库
- 移动端多人视频通讯软件开发(一)-- 前言
- Java:Object类详解