1、如何对APK签名
(1)、创建数字证书,android123.keystore
keytool -genkey -alias android123.keystore -keyalg RSA -validity 20000 -keystore android123.keystore
keytool工具是Java JDK自带的证书工具
-genkey参数表示:要生成一个证书(版权、身份识别的安全证书)
-alias参数表示:证书有别名,-alias android123.keystore表示证书别名为android123.keystore
-keyalg RSA表示加密类型,RSA表示需要加密,以防止别人盗取
-validity 20000表示有效时间20000天
-keystore android123.keystore表示要生成的证书名称为android123.keystore
Enter key password for <android123.keystore>
(RETURN if same as keystore password):此时按回车
生成的数字证书android123.keystore里面包换了非对称加密的私钥、公钥和证书。 (2)、使用数字证书进行签名
jarsigner -verbose -keystore android123.keystore -signedjar test_signed.apk test.apk android123.keystore
jarsigner是Java的签名工具
-verbose参数表示:显示出签名详细信息
-keystore表示使用当前目录中的android123.keystore签名证书文件。
-signedjar test_signed.apk表示签名后生成的APK名称,test.apk表示未签名的APK Android软件, android.keystore表示别名
(3)、签名后生成了META-INT文件夹,里面包含的文件如下:
通过这三个文件,我们了解下第二步中jarsigner都做了什么事情,我们先看MANIFEST.MF,如下:
Manifest-Version: 1.0
Created-By: 1.0 (Android)
Name: res/raw/aes.lua
SHA1-Digest: M2O7Kjh31bRSTSaX9Kxeg9+r8t0=
Name: AndroidManifest.xml
SHA1-Digest: gJSLROnRQjVNfuSf9ZLQ/jcfjCQ=
Name: lib/armeabi-v7a/libuencrypt.so
SHA1-Digest: 60nq3GlIOFjA2qQwpD0GHF0B+fs=
Name: assets/aes.lua
SHA1-Digest: M2O7Kjh31bRSTSaX9Kxeg9+r8t0=
Name: res/drawable-hdpi-v4/ic_launcher.png
SHA1-Digest: Nq8q3HeTluE5JNCBpVvNy3BXtJI=
Name: res/layout/activity_main.xml
SHA1-Digest: 29xFOv25tmFws/fZywW1pnKb0/0=
Name: res/layout/lv_item.xml
SHA1-Digest: n+ABu8eXc8sgsr/koDg/u1UIHsk=
Name: res/drawable-mdpi-v4/ic_launcher.png
SHA1-Digest: RRxOSvpmhVfCwiprVV/wZlaqQpw=
Name: res/menu/main.xml
SHA1-Digest: FwPQ14VCI33UrtPR12pUamCNBtI=
Name: lib/armeabi-v7a/libalgms.so
SHA1-Digest: l6EtvZsMbYZLCRF/ym+gDCbb66A=
Name: res/layout/gv_item.xml
SHA1-Digest: zJG1Od3RKnHgvtNspfJoL3Gjl9c=
Name: res/drawable-xhdpi-v4/ic_launcher.png
SHA1-Digest: AfPh3OJoypH966MludSW6f1RHg4=
Name: lib/armeabi/libluajava.so
SHA1-Digest: hEXHJ2RO/N4HG7HpkvNLpwkezx8=
Name: resources.arsc
SHA1-Digest: xvke7fWkq3vTndO6GxJygC191Io=
Name: lib/armeabi-v7a/libluajava.so
SHA1-Digest: G1oHj8pHfhE6cTmiIIyLf7q3g5I=
Name: res/layout/notify.xml
SHA1-Digest: cwi7OQR/TBBCikvfrG1mWb/7aQ8=
Name: classes.dex
SHA1-Digest: ZFp/aGRiQlOrGaeCybupky6xL9w=
Name: res/drawable-xxhdpi-v4/ic_launcher.png
SHA1-Digest: GVIfdEOBv4gEny2T1jDhGGsZOBo=
Name: lib/armeabi/libalgms.so
SHA1-Digest: sThUrFV9sUiv9GDot0L92RkYBPs=
Name: lib/armeabi/libuencrypt.so
SHA1-Digest: 60nq3GlIOFjA2qQwpD0GHF0B+fs=
里面包含了所有apk中资源分别求Hash值。
我们再看CERT.SF,如下:
Signature-Version: 1.0
SHA1-Digest-Manifest: rpk81cwms7B69LRe8+DWDOXsXh4=
Created-By: 1.0 (Android)
Name: res/raw/aes.lua
SHA1-Digest: 328J86FdzrMHCGbJ9zgSIL66Vhg=
Name: AndroidManifest.xml
SHA1-Digest: 5FgYlUZJI5rg9CliE7aY0lJvQeA=
Name: lib/armeabi-v7a/libuencrypt.so
SHA1-Digest: c4LKMukodajHJes+c40iIKVR5Mc=
Name: assets/aes.lua
SHA1-Digest: bxsaWYSVcIxoulpdWPfY0BV2PiQ=
Name: res/drawable-hdpi-v4/ic_launcher.png
SHA1-Digest: nVLQ/wUjf9D4KSB2I7WqoHR14JY=
Name: res/layout/activity_main.xml
SHA1-Digest: JW6OyAas5Wk9A3gkVFXQfnW5/xM=
Name: res/layout/lv_item.xml
SHA1-Digest: dNWFJFprP0T6rcGEzItXC7wCYkM=
Name: res/drawable-mdpi-v4/ic_launcher.png
SHA1-Digest: NBFXy1maYHW4TAiVCw6R9+EBNqI=
Name: res/menu/main.xml
SHA1-Digest: OKnRLZ88PSIyuOBi7mLTP2st5qo=
Name: lib/armeabi-v7a/libalgms.so
SHA1-Digest: FtY/V2plAUjgAuML1e13WkbAlv4=
Name: res/layout/gv_item.xml
SHA1-Digest: dkF+JesLgH0dGCDQ3n8xB5x27/c=
Name: res/drawable-xhdpi-v4/ic_launcher.png
SHA1-Digest: qLB+xSuTsdod1eS2aPJel/A5PvE=
Name: lib/armeabi/libluajava.so
SHA1-Digest: s4qgp8flPTMEZkF8z5QutBgFxrM=
Name: resources.arsc
SHA1-Digest: 541ycGJWJPTgwVyrgsxvB8pjjCM=
Name: lib/armeabi-v7a/libluajava.so
SHA1-Digest: Ef0wS9E2VVNlCobz+Rfus6H98sQ=
Name: res/layout/notify.xml
SHA1-Digest: ioOWjUP2Gg9EEwhuElzwisdCR6I=
Name: classes.dex
SHA1-Digest: K7z+duqJFBCe/hMgJWJQrzmLwxE=
Name: res/drawable-xxhdpi-v4/ic_launcher.png
SHA1-Digest: W7nSszMeL1x0eIt3K2CoCIHU6Qg=
Name: lib/armeabi/libalgms.so
SHA1-Digest: +F1sBBeuDvU3e9uqpFyvdOSdQAE=
Name: lib/armeabi/libuencrypt.so
SHA1-Digest: JToW2wKlog94dVZeNv3cGOC3CwA=
首先对
MANIFEST.MF整个文件求Hash值存放在SHA1-Digest-Manifest中,然后再对MANIFEST.MF里面的Hash值再求Hash值。
最后我们再来看,CERT.RSA,它是个二进制文件。只能通过特定的工具读出来其中的内容。可参考从CERT.RSA中提取证书一文。
读出来的内容如下,参考Android签名与认证详细分析之二(CERT.RSA剖析),如下图:
我们先看最后一步的已加密的Hash值,这是对CERT.SF文件求Hash值然后使用私钥加密后的结果。
再往上看密钥,这里的密钥指的是非对称加密的公钥。这个文件中不保存对称加密的私钥。
CERT.RSA还保存了发行者名称和主体名称,生效日期和终止日期等待。
了解了这个三个文件的内容,我们也就知道了jarsigner都做了什么事情。
2、签名的作用
(1)保证内容的完整性
在安装APK时,计算APK中每个资源的Hash值与MANIFEST.MF里面的Hash值做对比;如果成功,再计算MANIFEST.MF文件的Hash值与CERT.SF的Hash值做对比;如果成功,使用公钥解密CERT.RSA已加密的Hash值,然后与对CERT.SF文件求出的Hash值做对比;如果成功,表示验证通过。
如果恶意修改代码,再恶意修改MANIFEST.MF对应的Hash值,再恶意修改CERT.SF的Hash值,但是最后无法修改CERT.RSA里面的Hash值,因为没有私钥。
1)如果当前的APK被篡改,直接放入手机中运行,第一步在计算APK中每个资源的Hash值与MANIFEST.MF里面的Hash值做对比,这一步就Failed了。
2)如果当前的APK被篡改后重新签名,由于系统中原有同样包名的apk,发现与原有签名的公钥不一致,直接被reject。除非把原应用删除,再安装新的应用。
(2)shareUid
如果两个应用shareUid,说明两个应用可以对对方的私有目录进行访问,这就造成了安全隐患。如果360和QQ,sharedUid,那么360就可以访问QQ目录下(/data/data/com.tencent/...)的私有数据。所以我们规定shardUid的两个应用必须使用同样的私钥进行签名,在CERT.RSA体现在公钥一致。
本文详细介绍了Android APK的签名过程,包括如何使用keytool创建数字证书,使用jarsigner进行签名,以及签名后生成的META-INF文件夹内容。签名的主要作用在于确保内容完整性和防止恶意篡改。此外,还提到了签名对于shareUid安全性的关键作用。
4万+

被折叠的 条评论
为什么被折叠?



