‘壹’ android V1及V2签名原理简析
Android为了保证系统及应用的安全性,在安装APK的时候需要校验包的完整性,同时,对于覆盖安装的场景还要校验新旧是否匹配,这两者都是通过Android签名机制来进行保证的,本文就简单看下Android的签名与校验原理,分一下几个部分分析下:
签名是摘要与非对称密钥加密相相结合的产物,摘要就像内容的一个指纹信息,一旦内容被篡改,摘要就会改变,签名是摘要的加密结果,摘要改变,签名也会失效。Android APK签名也是这个道理,如果APK签名跟内容对应不起来,Android系统就认为APK内容被篡改了,从而拒绝安装,以保证系统的安全性。目前Android有三种签名V1、V2(N)、V3(P),本文只看前两种V1跟V2,对于V3的轮密先不考虑。先看下只有V1签名后APK的样式:
再看下只有V2签名的APK包样式:
同时具有V1 V2签名:
可以看到,如果只有V2签名,那么APK包内容几乎是没有改动的,META_INF中不会有新增文件,按Google官方文档:在使用v2签名方案进行签名时,会在APK文件中插入一个APK签名分块,该分块位于zip中央目录部分之前并紧邻该部分。在APK签名分块内, 签名和签名者身份信息会存储在APK签名方案v2分块中,保证整个APK文件不可修改 ,如下图:
而V1签名是通过META-INF中的三个文件保证签名及信息的完整性:
V1签名是如何保证信息的完整性呢?V1签名主要包含三部分内容,如果狭义上说签名跟公钥的话,仅仅在.rsa文件中,V1签名的三个文件其实是一套机制,不能单单拿一个来说事,
如果对APK中的资源文件进行了替换,那么该资源的摘要必定发生改变,如果没有修改MANIFEST.MF中的信息,那么在安装时候V1校验就会失败,无法安装,不过如果篡改文件的同时,也修改其MANIFEST.MF中的摘要值,那么MANIFEST.MF校验就可以绕过。
CERT.SF个人觉得有点像冗余,更像对文件完整性的二次保证,同绕过MANIFEST.MF一样,.SF校验也很容易被绕过。
CERT.RSA与CERT.SF是相互对应的,两者名字前缀必须一致,不知道算不算一个无聊的标准。看下CERT.RSA文件内容:
CERT.RSA文件里面存储了证书公钥、过期日期、发行人、加密算法等信息,根据公钥及加密算法,Android系统就能计算出CERT.SF的摘要信息,其严格的格式如下:
从CERT.RSA中,我们能获的证书的指纹信息,在微信分享、第三方SDK申请的时候经常用到,其实就是公钥+开发者信息的一个签名:
除了CERT.RSA文件,其余两个签名文件其实跟keystore没什么关系,主要是文件自身的摘要及二次摘要,用不同的keystore进行签名,生成的MANIFEST.MF与CERT.SF都是一样的,不同的只有CERT.RSA签名文件。也就是说前两者主要保证各个文件的完整性,CERT.RSA从整体上保证APK的来源及完整性,不过META_INF中的文件不在校验范围中,这也是V1的一个缺点。V2签名又是如何保证信息的完整性呢?
前面说过V1签名中文件的完整性很容易被绕过,可以理解 单个文件完整性校验的意义并不是很大 ,安装的时候反而耗时,不如采用更加简单的便捷的校验方式。V2签名就不针对单个文件校验了,而是 针对APK进行校验 ,将APK分成1M的块,对每个块计算值摘要,之后针对所有摘要进行摘要,再利用摘要进行签名。
也就是说,V2摘要签名分两级,第一级是对APK文件的1、3 、4 部分进行摘要,第二级是对第一级的摘要集合进行摘要,然后利用秘钥进行签名。安装的时候,块摘要可以并行处理,这样可以提高校验速度。
APK是先摘要,再签名,先看下摘要的定义:Message Digest:摘要是对消息数据执行一个单向Hash,从而生成一个固定长度的Hash值,这个值就是消息摘要,至于常听到的MD5、SHA1都是摘要算法的一种。理论上说,摘要一定会有碰撞,但只要保证有限长度内碰撞率很低就可以,这样就能利用摘要来保证消息的完整性,只要消息被篡改,摘要一定会发生改变。但是,如果消息跟摘要同时被修改,那就无从得知了。
而数字签名是什么呢(公钥数字签名),利用非对称加密技术,通过私钥对摘要进行加密,产生一个字符串,这个字符串+公钥证书就可以看做消息的数字签名,如RSA就是常用的非对称加密算法。在没有私钥的前提下,非对称加密算法能确保别人无法伪造签名,因此数字签名也是对发送者信息真实性的一个有效证明。不过由于Android的keystore证书是自签名的,没有第三方权威机构认证,用户可以自行生成keystore,Android签名方案无法保证APK不被二次签名。
知道了摘要跟签名的概念后,再来看看Android的签名文件怎么来的?如何影响原来APK包?通过sdk中的apksign来对一个APK进行签名的命令如下:
其主要实现在 android/platform/tools/apksig 文件夹中,主体是ApkSigner.java的sign函数,函数比较长,分几步分析
先来看这一步,ApkUtils.findZipSections,这个函数主要是解析APK文件,获得ZIP格式的一些简单信息,并返回一个ZipSections,
ZipSections包含了ZIP文件格式的一些信息,比如中央目录信息、中央目录结尾信息等,对比到zip文件格式如下:
获取到 ZipSections之后,就可以进一步解析APK这个ZIP包,继续走后面的签名流程,
可以看到先进行了一个V2签名的检验,这里是用来签名,为什么先检验了一次?第一次签名的时候会直接走这个异常逻辑分支,重复签名的时候才能获到取之前的V2签名,怀疑这里获取V2签名的目的应该是为了排除V2签名,并获取V2签名以外的数据块,因为签名本身不能被算入到签名中,之后会解析中央目录区,构建一个DefaultApkSignerEngine用于签名
先解析中央目录区,获取AndroidManifest文件,获取minSdkVersion(影响签名算法),并构建DefaultApkSignerEngine,默认情况下V1 V2签名都是打开的。
第五步与第六步的主要工作是:apk的预处理,包括目录的一些排序之类的工作,应该是为了更高效处理签名,预处理结束后,就开始签名流程,首先做的是V1签名(默认存在,除非主动关闭):
步骤7、8、9都可以看做是V1签名的处理逻辑,主要在V1SchemeSigner中处理,其中包括创建META-INFO文件夹下的一些签名文件,更新中央目录、更新中央目录结尾等,流程不复杂,不在赘述,简单流程就是:
这里特殊提一下重复签名的问题: 对一个已经V1签名的APK再次V1签名不会有任何问题 ,原理就是:再次签名的时候,会排除之前的签名文件。
可以看到目录、META-INF文件夹下的文件、sf、rsa等结尾的文件都不会被V1签名进行处理,所以这里不用担心多次签名的问题。接下来就是处理V2签名。
V2SchemeSigner处理V2签名,逻辑比较清晰,直接对V1签名过的APK进行分块摘要,再集合签名,V2签名不会改变之前V1签名后的任何信息,签名后,在中央目录前添加V2签名块,并更新中央目录结尾信息,因为V2签名后,中央目录的偏移会再次改变:
签名校验的过程可以看做签名的逆向,只不过覆盖安装可能还要校验公钥及证书信息一致,否则覆盖安装会失败。签名校验的入口在PackageManagerService的install里,安装官方文档,7.0以上的手机优先检测V2签名,如果V2签名不存在,再校验V1签名,对于7.0以下的手机,不存在V2签名校验机制,只会校验V1,所以,如果你的App的miniSdkVersion<24(N),那么你的签名方式必须内含V1签名:
校验流程就是签名的逆向,了解签名流程即可,本文不求甚解,有兴趣自己去分析,只是额外提下覆盖安装,覆盖安装除了检验APK自己的完整性以外,还要校验证书是否一致只有证书一致(同一个keystore签名),才有可能覆盖升级。覆盖安装同全新安装相比较多了几个校验
这里只关心证书部分:
Android V1及V2签名签名原理简析
仅供参考,欢迎指正
‘贰’ Android studio北极狐版本没有v1签名
因为Android studio不支持v1签名,
把V1和V2两个选项全部勾选,就可以了,
‘叁’ Android studio 如何创建apk签名
1、打开软件
找到“Build”选项
2、打开生成apk签名的窗口
Build---->Generate Signed APK...
3、 选择创建新的密钥
Creata new...
4、 选择密钥存储路径,并为密钥命名
填写信息
5、设置密码,填写或更改信息
密码请牢记,密码请牢记,密码请牢记(三遍了)
证书内容貌似可以空白
6、ok,然后,下一步
如果遇到下图的情况,不用担心,继续点击ok
问题解决办法:https://www.jianshu.com/p/67c2972182a0
7、然后,下一步
8、选择签名版本
v1或者v1&v2 然后点击finish 即可,找到刚才保存的路径,即可找到签名文件
建议选择v1&v2
‘肆’ Android Studio的Signature Versions选择,分别是什么意思
Signature Versions
签名版本
‘伍’ Android Studio 运行时模拟器部分出错:求解答
问题一,解决办法有如下这些:
重启Eclipse,方法File—>Restart。
尝试重启ADB服务。
你可以在sdk目录如c:\Program Files\Android\android-sdk-windows\platform-tools\下建一个叫restartADB.bat的windows批处理文件,文件中写入:
adb kill-server && adb start-server
pause
需要重启ADB,只要双击运行文件即可,注意adb.exe须在platform-tools目录下,不然脚本可能运行不了
删除Run Configuration,在Run—>Run Configuration中,选择删除已经配置的Activity。
尝试删除你的.android文件下的一些镜像文件。按你问题提供的信息,应该在:C:\Users\lgs\.android\avd\androidAddresslist.avd/sdcard.img
C:\Users\lgs\.android\avd\androidAddresslist.avd/sdcard.img
C:\Users\lgs\.android\avd\androidAddresslist.avd/userdata-qemu.img
问题二,解决方法有:
1.重启Eclipse,重启ADB。
2.如果上面方法不行,看一下有没有类似91手机助手,腾讯手机助手等工具正在开启,有的话就结束掉这些工具对应的进程。
3.如果你的sdk还是2.3以下的旧版本,那么就是把tools文件夹中的adb.exe复制到platform-tools文件夹中。构组成编辑
在IDEA的基础上,Android Studio 提供[1] :
基于Gradle的构建支持
Android 专属的重构和快速修复
提示工具以捕获性能、可用性、版本兼容性等问题
支持ProGuard 和应用签名
基于模板的向导来生成常用的 Android 应用设计和组件
功能强大的布局编辑器,可以让你拖拉 UI 控件并进行效果预览
主要功能编辑
2013年
2013年5月16日,在I/O大会上,谷歌推出新的Android开发环境——Android Studio,并对开发者控制台进行了改进,增加了五个新的功能[2] 。
Android Studio是谷歌推出了新的Android开发环境,开发者可以在编写程序的同时看到自己的应用在不同尺寸屏幕中的样子。
谷歌对开发者控制台进行了改进,增加了五个新的功能,包括优化小贴士、应用翻译服务、推荐跟踪、营收曲线图、用版测试和阶段性展示。
1、优化小贴士:在主体中打开你的应用,点击小贴士,会得到这样的建议:为你的应用开发平板电脑版本。
2、应用翻译服务:允许开发者直接在开发主体中获得专业的翻译。上传你的需求,选择翻译,其会显示翻译方和价格,并在一周内发回译本。
3、推荐跟踪:允许开发者找出最有效的广告
4、营收曲线图:向开发者展示其应用营收,以国家进行划分
5、试用版测试和阶段性展示:开发者可以对应用进行测试,然后向测试用户推出,测试结果不会对外公布。当一个版本的测试结束,开发者可以向特定比例用户推出[3] 。
Android Studio这款开发工具被首次公布,这也是为了方便开发者基于Android开发。
首先解决的一个问题是多分辨率。Android设备拥有大量不同尺寸的屏幕和分辨率,根据新的Studio,开发者可以很方便的调整在各个分辨率设备上的应用。
同时Studio还解决语言问题,多语言版本(但是没有中文版本)、支持翻译都让开发者更适应全球开发环境。Studio还提供收入记录功能。
最大的改变在于Beta测试的功能。Studio提供了Beta Testing,可以让开发者很方便试运行[1] 。
2015年
2015年5月29日,在谷歌I/O开发者大会上,谷歌发布AndroidStudio 1.3版,支持C++编辑和查错功能。Android Studio 1.3版开发码代码变得更加容易,速度提升,而且支持C++编辑和查错功能[4] 。
版本更新编辑
Android Studio v0.3.1
Platform
Package
Size
MD5 Checksum
Windows
android-studio-bundle-132.883541-windows.exe
448245492 bytes
Mac OS X
android-studio-bundle-132.883541-mac.dmg
427317993 bytes
linux
android-studio-bundle-132.883541-linux.tgz
451652493 bytes
[5]
Android Studio v0.3.2
Platform Package Size MD5 Checksum
Windows android-studio-bundle-132.893413-windows.exe 484345454 bytes
Mac OS X android-studio-bundle-132.893413-mac.dmg 463332508 bytes
Linux android-studio-bundle-132.893413-linux.tgz 487694946 bytes
9f1306
100314b03ff5b691b94f154501
[6]
Android Studio v0.4.2
Platform Package Size MD5 Checksum
Windows android-studio-bundle-133.970939-windows.exe 51701 bytes
Mac OS X android-studio-bundle-133.970939-mac.dmg 491773471 bytes
Linux android-studio-bundle-133.970939-linux.tgz 516080363 bytes
[7]
Android Studio v0.4.6
Platform Package Size MD5 Checksum
Windows android-studio-bundle-133.1028713-windows.exe 519592042 bytes
Mac OS X android-studio-bundle-133.1028713-mac.dmg 497595811 bytes
Linux android-studio-bundle-133.1028713-linux.tgz 522177460 bytes
[8]
ANDROID STUDIO V0.8.0
Platform Package Size MD5 Checksum
Windows android-studio-bundle-135.1245622-windows.exe 380000036 bytes
Mac OS X android-studio-bundle-135.1245622-mac.dmg 368451923 bytes
Linux android-studio-bundle-135.1245622-linux.tgz 417756987 bytes
[9]
启动解决方案编辑
先来到Android Studio的bin目录下,修改studio.bat 第72行GOTO end 在它前面加上PAUSE 用于查看错误消息,进入cmd 然后指向Android Studio目录下 运行studio.bat 可以查看错误消息,去修改android-studio\bin目录下的studio.exe.vmoptions 去除第5行的 -XX:+UseCodeCacheFlushing,启动成功
用记事本打开android-studio\bin 目录下的studio.bat
将 SET VM_OPTIONS_FILE=%IDE_BIN_DIR%\studio%BITS%.exe.vmoptions
改为 SETVM_OPTIONS_FILE=%IDE_BIN_DIR%\studio%BITS%.exe启动成功[10]
用文本工具打开
studio.bat
line25 to line 28:
SET JRE=%JDK%
IF EXIST "%JRE%\jre" SET JRE=%JDK%\jre
SET BITS=IF EXIST "%JRE%\lib\amd64" SET BITS=64
可以看到里面设置软件支持系统位数是64位,如果自己所用电脑是32位的 jre/lib目录下只有i386文件,尝试把
IF EXIST "%JRE%\lib\amd64" SET BITS=64 改为
IF EXIST "%JRE%\lib\i386" SET BITS=32[10]
检查jdk路径是否配置,1.6和1.7都没有问题,jdk环境变量配置确保正确。[10]
Android Studio 0.2 Released
Jun 6, 2013 Google released Android Studio 0.1.3.[11]
‘陆’ android studio高德地图加载离线地图如何做
一、注册开发者账号,新建新Key。
二、首先根据高德地图开发者获取key。
androidstudio获取SHA1方法:打开androidstudio的Termina(alt+F12),输入命令:keytool -v -list -keystore keystore文件路径(默认路径 C:\Users\用户名\.android debug.keystore),默认密码:android,即可获取SHA1。
PackageName为app中build。gradle中的applicationId。
三、打开AndroidStudio-->Build-->Generate Signed APK-->Create new...,创建新的key,按照图示创建即可,要记下Alias的名字和密码,然后选择第V2-->finish即可。
四、新建工程,将下载的SDK的jar包复制到工程libs下,并add as library(复制→粘贴到文件夹下即可)。
五、3D地图需要添加so库:在main目录下创建jniLibs,将下载的so库文件拷贝到这个目录下。
‘柒’ 如何在Android studio中使用之前eclispe中用的签名文件
在签名的时候选择这钱使用的签名文件,输入密码,点击选择以前签名时的对应名称(会自动检测签名文件信息的,所以直接能看到),之后按照提示操作就行了。如果你的android studio是2.3版本,需要选择v1还是v2方式,选择v1就行
‘捌’ android studio写的程序在安卓7.1提示安装包异常,安卓8.1安装后无法打开怎么解决
你好,请问安装包是否进行了签名?或者签名的时候,是否选择了V1和V2。
APK包没有签名,在7.1以上系统会报异常。
如果是签名的,请同时使用V1,V2方式签名。V1签名只能在7.0以下系统安装,v2签名可以在7.0以上系统安装。
‘玖’ androidstudio2.3打包apkv1和v2的区别
1、选中需要打包的mole,然后点击菜单“Build——>Build APK”,在本地打包debug和debug-unsigned版本的APK
2、选中“Generate Signed APK”生成签名的APK
‘拾’ android studio中的drawable-v24怎么创建
我们一般将APP的icon放在minmap文件夹下,其他图片资源放在drawable文件夹下。下面我们看下AndroidStudio下如何创建drawable、drawable-hdpi、drawable-mdpi、drawable-xhdpi、drawable-xxhdpi。
1、切换到Project视图下,找到对应moudle的res文件夹,右击“res”--》 “new”--》“Android resource directory”,弹出“New Resource Directory”对话框。
2、按照上图的一二三步骤,点击第三步后,会出现一下内容,选择要添加drawable的分辨率,点击“ok”按钮即可。