赞
踩
在验证期间,v2+ 方案会将 APK 文件视为 blob
,并对整个文件进行签名检查。对 APK 进行的任何修改(包括对 ZIP 元数据进行的修改)都会使 APK 签名作废。这种形式的 APK 验证不仅速度要快得多,而且能够发现更多种未经授权的修改。
新的签名格式向后兼容,因此,使用这种新格式签名的 APK 可在更低版本的 Android
设备上进行安装(会直接忽略添加到 APK 的额外数据),但前提是这些 APK 还带有 v1 签名。
从安全的角度 v2 会比 v1 更安全,v2 签名是验证整个打包后的 APK 文件,所以对其 APK 文件做「任何」改动都会破坏签名。注意这里的任何是带引号的,V2签名的签名块其实是一个 K-V
的结构,可以向其中插入一些简单的数据而不破坏 v2 签名,这就是 v2 方案下,多渠道的方案思路。
缺点是:无法解决签名过期更换签名的问题。
v2
签名会更安全。v2
签名是对整个 Apk
进行签名验证,不需要解压验证,所以签名验证的时间会更短。v2 方案解决了安全问题以及安装时验证的效率问题,但是它并没有解决更换签名问题。
Android 9.0
中引入了新的签名方式,它的格式大体和 v2 类似,在 v2 插入的签名块(Apk Signature Block v2
)中,又添加了一个新快(Attr块)。
在这个新块中,会记录之前的签名信息以及新的签名信息,以密钥转轮
的方案,来做签名的替换和升级。这意味着,只要旧签名证书在手,就可以通过它在新的 APK 文件中,更改签名。
V3 签名新增的新块(attr
)存储了所有的签名信息,由更小的 Level
块,以链表的形式存储。
其中每个节点都包含用于为之前版本的应用签名的签名证书,最旧的签名证书对应根节点,系统会让每个节点中的证书为列表中下一个证书签名,从而为每个新密钥提供证据来证明它应该像旧密钥一样可信。
这个过程有点类似 CA 证书的证明过程,已安装的 App 的旧签名,确保覆盖安装的 APK 的新签名正确,将信任传递下去。
在传统的应用安装方案中,开发者通过 ADB(Android Debug Bridge
)以有线或无线的方式与终端用户连接,或者用户从软件商店直接下载,然而该方案需要用户等待完整的安装包传输结束后才能启动安装,在这期间产生了不良的用户体验。
增量安装技术是一种流式安装方案:一旦安装包的核心文件传输完成便可启动应用。流式安装意味着允许优先传输核心数据以启动应用,并在后台流式传输剩余数据。
在Android 11中,Google在内核中实现了增量文件系统用于对增量安装的支持。
这使得 Android os 可以通过 ADB 流式传输 APK。同时,Android 11 为了适应增量安装,添加了新的 v4签名方案。
此方案不改变前代签名方案而是创建一种新的签名:基于 APK 所有字节数据计算出 Merkle 哈希树
,并将Merkle 树的根哈希、盐值作为签名数据进行包完整性验证。新的签名数据保存在 .idsig
文件中并且在进行增量安装前必须为APK创建对应的 v4 签名文件。
官方文档:v4签名
- v1 签名实际上就是 JAR 签名的方案,它不会保护 APK 内的所有文件,存在安全和效率问题;
- v2 签名是一种全文件签名方案,增加了 APK 签名块(
APK Signing Block
),但仍无法解决更换签名的问题;- v3 签名是 v2 的升级版,也被称为 v2+。在 V2 插入的签名块(
Apk Signature Block V2
)中,又添加了一个新快(Attr 块),它使用链表存储了所有的签名信息,验证时就像 CA 证书的证明过程。- v4 签名是为了增量安装技术而产生的一种新的签名方案。
如果想无缝升级一个应用,Android系统要求应用程序的新版本与老版本具有相同的签名与包名。若包名相同而签名不同,系统会拒绝安装新版应用。
若APK签名策略由V1
升级至V1+V2+V3
,且升级前后的APP签名与包名保持一致,则可以做到无缝升级。
按照以下步骤实现APK签名、校验。
apksigner
签名(签名结果:V1+V2+V3
)apksigner sign --ks android.jks --ks-key-alias android --out signed.apk unsigned.apk
keytool -v -list -keystore xxx.jks
keytool -printcert -jarfile ./weixin806android1900_arm64.apk
apksigner verify --verbose signed.apk
packageName
、versionCode
等info)aapt dump badging test.apk
jarsigner
是 JDK
提供的针对 jar
包签名的工具,如果你本地已经安装了 Java
环境,会自带 jarsigner
,
比如我的 jarsigner
工具的位置在
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/bin/jarsigner
效果图如下:
apksigner
是 Google
官方提供的针对 Android Apk
签名和验证的专用工具,位于 Android SDK / build-tools / SDK 版本 / apksigner
。
以我本地的 Android SDK 30.0.2
版本为例, apksigner
工具的位置在
/Users/suxing/Library/Android/sdk/build-tools/30.0.2/apksigner
。
效果图如下:
如果你用的是 Android Studio
或者 IDEA
,安装这两个编辑器时会自动下载 Android SDK
,所以 apksigner
工具也不需要另外安装。
不过,无论是 apk
包还是 jar
包,其本质都是 zip
格式的压缩包,如果只针对 v1
签名的话,两者的签名过程其实差不多。
apksigner
工具默认同时使用 v1
和 v2
签名,以兼容 Android 7
以下的系统版本。
为方便应用apksigner
签名,可将apksigner
径配置到系统环境变量path。实现步骤如下:
cd ~
open -e .bash_profile
source .bash_profile
.bash_profile
文件内容如下:
source ~/.bashrc # Git branch in prompt. parse\_git\_branch() { git branch 2> /dev/null | sed -e '/^[^\*]/d' -e 's/\* \(.\*\)/ (\1)/' } export PS1="\u@\h \W\[\033[32m\]\$(parse\_git\_branch)\[\033[00m\] $ " source ~/.bashrc export ANDROID\_HOME=/Users/ccms-m-03/Library/Android/sdk export PATH=${PATH}:${ANDROID\_HOME}/tools export PATH=${PATH}:${ANDROID\_HOME}/platform-tools export AAPT\_HOME=/Users/ccms-m-03/Library/Android/sdk/build-tools/30.0.3 export PATH=$PATH:$AAPT\_HOME source ~/.bashrc
apksigner
通过以下指令实现apk签名。
apksigner sign --ks android.jks --ks-key-alias android --out signed.apk unsigned.apk
--ks
.jks
文件路劲--ks-key-alias
签名文件别名--out
输出签名后的目标路径unsigned.apk
未签名的原始apk
文件路径
为了避免路径过长,书写错误的、问题,建议将加固包jks文件放置在同一目录。
其实从文件的大小我们就可以看到有变化,但是还得验证是否签名成功,用以下指令校验:
apksigner verify --verbose signed.apk
签名成功如下图:
没有签名如下提示:
签名后如果包能正确安装到手机(无需运行)则没有问题,如果安装失败请用命令安装:adb install apkfile
查看出错信息。
注⚠️:通过apksigner可视化工具签名后的签名方案为V1
,用apksigner sign --ks android.jks --ks-key-alias android --out signed.apk unsigned.apk
命令行签名后的签名方案为V1+V2+V3
!
解压后可查看META-INF
下.RSA
、 .SF
、 .MF
等文件的日期就是打包日期。
ios
可以查看 info.plist
文件的时间。
.jks
是在android studio
里面生成的签名证书。.keystore
是eclipse
里面生成的签名证书。两者在使用方式上没有什么区别,但是在算法上有一点区别。
在应用apksigner
可视化签名工具进行APK签名时,发现只支持.keystore
格式的签名文件,需要把.jks
签名格式转化为.keystore
格式。
直接用命令行转换,先生成.p12
文件,用.p12
生成.keystore
。
keytool -importkeystore -srckeystore test.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore test.p12
keytool -v -importkeystore -srckeystore test.p12 -srcstoretype PKCS12 -destkeystore test.keystore -deststoretype JKS
转换后,会看到如下提示信息。可以通过提示的命令行
keytool -importkeystore -srckeystore cicc-keystore.keystore -destkeystore cicc-keystore.keystore deststoretype pkcs12
按照指定行业标准格式进行转换。
Warning: JKS 密钥库使用专用格式。建议使用 “keytool -importkeystore -srckeystore
cicc-keystore.keystore -destkeystore cicc-keystore.keystore
-deststoretype pkcs12” 迁移到行业标准格式 PKCS12。
现在test.keystore
的签名应该与test.jks
的签名信息是一样的了。
可以通过以下命令来验证:
keytool -v -list -keystore test.keystore
同理,.keystore
也可以转.jks
,转换命令如下:
keytool -importkeystore -srckeystore test.keystore -srcstoretype JKS -deststoretype PKCS12 -destkeystore test.p12
keytool -v -importkeystore -srckeystore test.p12 -srcstoretype PKCS12 -destkeystore test.jks -deststoretype JKS
应用签名工具对APP做好签名后,如何验证签名的正确性,或者是给你一个apk,如何验证该apk是否完成了签名操作。
应用 keytool
工具可实现文件签名验证。
keytool -printcert -jarfile ./weixin806android1900_arm64.apk
若apk
为已签名,则会显示以下信息:
若apk
未签名,则会提示不是已签名的 jar 文件。
拓展阅读:KeyTool
是Java中的数字证书管理工具,用于数字证书的申请、导入、导出和撤销等证书管理操作,位于<JAVA_HOME>\bin\keytool.exe
。要获得数字证书需要使用数字证书管理工具(如KeyTool
和OpenSSL
)构建CSR
(Certificate Signing Request
,数字证书签发申请),交由CA
机构签发,形成最终的数字证书。
同样使用 keytool
工具查看 xxx.keystore
或者 xxx.jks
,注意查看自己的签名文件则需要密码输入才能查看。根据以下命令输出信息,通过对比apk签名输出的MD5
、sha
信息是否一致,一致则代表签名成功。
keytool -v -list -keystore xxx.jks
APP组好包之后,如何查看包信息?
首先找到aapt
工具,在Android SDK文件夹下的build-tools
包里应用aapt
命令便可实现查看Android APK信息。
或者将aapt
命令添加到环境变量。
然后,通过aapt
命令便可查看apk包的packageName、versionCode、applicationLabel、launcherActivity、permission
等各种详细信息
先 cd 到 apk 所在目录,然后执行以下命令 :
查看apk的基本配置信息
aapt dump badging test.apk
查看apk的权限
aapt dump permissions test.apk
查看apk的资源列表
aapt dump resources test.apk
一般都会输出很多的信息,如要全部查看,请用下面这个命令:
aapt dump resources test.apk > test.txt
这样会把所有的信息通过重定向符">
"输出到test.txt文件中,然后再打开该文件即可查看。
查看apk配置信息
aapt dump configurations test.apk
查看指定apk的指定xml文件,以树形结构输出的xml信息
aapt dump xmltree test.apk res/***.xml
输出xml文件中所有的字符串信息
aapt dump xmlstrings test.apk res/***.xml
主要是用于版本升级所用,是Integer
类型的,第一个版本定义为1,以后递增,这样只要判断该值就能确定是否需要升级,该值不显示给用户。
不要将versionCode
设置的太大,最好不要超过Integer
的取值范围,一般大发布第一个应用到市场的时候,版本取值为1(versionCode=1
),这也是目前典型和普遍的做法。
每次发布更新版本时可以递增versionCode
的值,一个新版本的应用的versionCode
不能小于之前旧版本的versionCode
值,否则进行替换更新升级时会出错,系统提示无法安装。这也不是强制的,只是正式发布应用时,建议必须考虑的问题。
注意⚠️: 同一个APP低版本是不能直接覆盖安装手机中已存在的高版本应用(通过版本号(versionCode
)来判断)。
这个是我们常说的版本号,这是一个值为String
类型的属性,由三部分组成<major>.<minor>.<point>
。VersionCode
是方便程序开发者运行和维护Application
而设置的一个有效值。versionName
是一个版本的描述,给用户看的,也是用户放在各个第三方平台上提供给使用者看的一个版本名,可以说是对VersionCode
的解释和描述。
其中,
major
是主版本号,一般在软件有重大升级时增长;minor
是次版本号,一般在软件有新功能时增长;maintenance
是维护版本,一般在软件有主要的问题修复后增长;解压IPA
安装包文件,然后通过打开APP
的信息文件:info.plist
来查看名称、Bundle ID、版本等基本信息,如果要查看证书文件名称,那就需要通过命令行工具:security 来查看描述文件:embedded.mobileprovision。
在第三方平台填的应用签名是不一样的,第三方平台填的签名信息是32位的。
注⚠️:应用签名由开发者签名该应用的.keystore
文件决定。
使用签名生成工具查看该应用的签名:
任意下载一个(是一个apk文件)安装手机后运行:
Android
平台配置CPU
类型针对的是为了提高运行效率,使用C/C++
语言开发生成的so
库,需要为各cpu
类型平台单独编译生成对应指令的so
库。Java
语言开发的代码运行在虚拟机中,基于虚拟机跨平台特性,由虚拟机适配CPU类型,不涉及到此问题。
HBuilder/HBuilderX
中使用so
库的功能(模块)如下:
Audio
(录音):支持mp3格式;Geolocation
(定位):百度;LivePush
(直播推流);Maps
(地图):高德、百度;OAuth
(登录鉴权):新浪微博;Push
(消息推送):个推、UniPush;Share
(分享):新浪微博;Speech
(语音输入):百度,注意:讯飞不支持64位;Weex
(原生渲染):uni-app
(自定义组件模式、nvue页面), 注意:HBuilderX2.1.5
及以上版本支持;注意⚠️:
HBuilderX2.7.0+
调整 云端打包默认不再包含 x86 CPU类型库,减少apk包体积详情;HBuilderX2.1.5+
开始支持Android
平台的新增适配64位CPU类型,云端打包支持配置App支持的CPU类型,满足Google Play从2019年8月1日起上传的App必需支持64位CPU的要求。HBulderX
已适配支持以下主流CPU类型:
x86
少部分平板使用x86,AS模拟器中选了intel x86时使用x86处理器,以及其它常用三方模拟器通常使用x86。
注意⚠️:不勾选x86在模拟器上可能无法正常运行,以下是常见模拟器是否需要包含x86的情况:
打开项目的manifest.json
文件,在 “App常用其它设置” -> “Android设置” -> “支持CPU类型”
项中勾选需要支持的CPU类型:
打开项目的manifest.json
文件,切换到“源码视图”,根据项目类型进行配置。
在 "app-plus"->"distribute"->"android"
节点的 abiFilters
属性配置支持的CPU
类型,示例如下:
"app-plus": {
"distribute": {
"android": {
"abiFilters": [
"armeabi-v7a",
"arm64-v8a"
]
//...
},
//...
},
//...
},
//..
使用Android studio
打开Android
原生项目,打开对应项目的build.gradle
文件。 在Android -> defaultConfig
下添加支持的CPU类型,如下示例:
defaultConfig{
ndk {
abiFilters 'arm64-v8a','armeabi-v7a'
}
}
注意:离线打包仅支持arm64-v8a、armeabi-v7a、x86
三种类型,建议根据自己需求选择打包的
ARM64位(arm64-v8a
)CPU可以兼容ARM32的指令,也就是说只选择armeabi-v7a
类型的so库也可以在64位手机上运行,只是没有完全发挥CPU的性能。 选择支持的CPU类型时请参考以下建议:
js前端的重头戏,值得花大部分时间学习。
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
这是288页的前端面试题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。