小白问一下 Android APK 数字签名相关地一个问题 - V2EX
YGHMXFAL

小白问一下 Android APK 数字签名相关地一个问题

  •  
  •   YGHMXFAL Apr 7, 2024 10054 views
    This topic created in 780 days ago, the information mentioned may be changed or developed.

    备份阶段:

    ●将常用软件+密码库+其它资源等等加密打包到①[All-In-One.7Z]

    ●把压缩包②[Passphrase]打印出来离线保存

    ●计算出③[SHA512(All-In-One.7Z)]并且打印出来离线保存

    ●把①[All-In-One.7Z]上传到多家墙内网盘

    ●计算出⑥[SHA512(ZArchiver.APK)]并且打印出来离线保存

    ●把⑤[ZArchiver.APK]上传到多家墙内网盘

    恢复阶段:

    (你买了一部新手机/二手手机,无法翻墙,因为存在和问题)

    ●从国产安卓内置应用商店中安装任一网盘 APP 并且登录

    ●从任一备份网盘下载①[All-In-One.7Z]+⑤[ZArchiver.APK]到本地存储

    ●立刻使用④[XXX]就地计算①[All-In-One.7Z]的“实际校验和”,并且与之前离线保存得“理论校验和”(即③)比较,匹配一致则证明压缩包完好无损,否则从头再来

    ●继续使用④[XXX]计算⑤[ZArchiver.APK]的“实际校验和”,并且与之前离线保存得“理论校验和”(即⑥)比较,匹配一致则证明 APK 完好无损并且立刻安装之,否则从头再来

    ●使用 ZArchiver 搭配之前离线保存得②[Passphrase]解压①[All-In-One.7Z]到任意本地目录

    ●Enjoy~

    我的问题是:

    大家明显能看出来④[XXX]是整个流程中的罩门:因为我全程假定其“已经安装”并且“可信”,事实上在一部新手机上这俩点都不成立

    实际上,④[XXX]应该和⑤[ZArchiver.APK]拥有一模一样地备份恢复流程,但是如果那样问题就又变成了“在没有安装我的前提下,执行我然后计算我的 HASH”,这又是一个和的问题了

    我的想法是:

    ●先参照⑤[ZArchiver.APK]的流程来备份④[XXX],但是微调恢复流程:

    从任一网盘下载④[XXX]的 APK 后,先不校验,无脑安装之(显然此时④[XXX]为“不可信”状态)

    启动④[XXX],计算网盘下载目录中④[XXX]的 APK 的“实际校验和”,并且与之前离线保存得“理论校验和”比较,匹配一致则证明 APK 完好无损(并且不需要安装了),否则从头再来

    我的问题是:此时能否判定④[XXX]为“可信”状态了?

    或者问得更具体一点儿:

    如果网盘服务商作恶,技术上是否存在这样地可能:构造一个[FakeXXX]来替换我上传得④[XXX],更改源代码,在其中硬编码一些逻辑/信息,使得使用[FakeXXX]来计算[FakeXXX]的 APK 所产生得结果总是我离线保存得“理论校验和”呢?

    ●如果实在没有办法,只能借助外力,在已经构建好了全套流程地 WINDOWS(见文末解释)上校验④[XXX],确认完好无损后将其 APK 存储到双插口 U 盘(此类 U 盘既可连接标准 USB 插口被 WINDOWS 读写,也可连接手机 TYPE-C 插口被 ANDROID 读写),然后在安卓自带文件管理器中安装

    ●或者大家还有什么建议/方案呢?因为我这几天搜索了解到,Android APK 其实自带数字签名,但是和 WINDOWS EXE/MSI 自带地数字签名不一样,Android APK 自带地数字签名似乎不依赖 CA 来为开发者身份背书?或者说 Android 其实放行任意 CA?这也是 Android 开放性的根源?

    注:其实此全套流程已经在 WINDOWS 上构建了,④[XXX]的替代品我选择了[],因为它自带数字签名(解决了“可信”问题),并且自带 SHA***SUM.EXE,并且是开源程序

    15 replies    2024-04-08 10:33:26 +08:00
    YGHMXFAL
        1
    YGHMXFAL  
    OP
       Apr 7, 2024
    文末的“注”漏了“我选择了[git for windows]”
    linhua
        2
    linhua  
       Apr 7, 2024   1
    安卓也自带 SHA***SUM

    adb shell

    130|HWEML:/ $ sha

    sha1sum sha224sum sha256sum sha384sum sha512sum
    YGHMXFAL
        3
    YGHMXFAL  
    OP
       Apr 7, 2024
    @linhua

    嗯,通过 ADB 访问 SHELL,

    也要数据线连接电脑吧?哪怕是无线 ADB 也要先数据线连接一次吧?那不如上 U 盘了~

    要是从 Android 本地访问 SHELL,哪怕不提 Root 权限,也要额外安装 APP(叫终端模拟器?),这个 APP 又要校验哇,又回到原点了呀
    rb6221
        4
    rb6221  
       Apr 7, 2024   1
    好晕。。。。
    安卓的签名只是保证这个安装包是来自开发者的
    不知道你追求的是哪方面的可信,如果是追求包不被篡改,那这个完全是没必要的,因为只要你从官方渠道下载的包,那都是来自开发者的,这一点商店会给你校验

    那么你一定要担心这个包从一开始就是签被篡改了对吧?大部分情况下是不会的,因为企业级产品,在运行的时候就会有检查签名的代码,否则各种破解版 xxx 就满天飞了。(以前是很泛滥,现在没了,主要就是这方面的规范起来了)


    正确的逻辑应该是,保存一个本地的 VPN 安装包。新手机入手以后,直接安装本地这个包,挂梯子,然后后续的步骤都走官方应用商店。
    YGHMXFAL
        5
    YGHMXFAL  
    OP
       Apr 7, 2024
    @janus77

    我的疑虑是:解压 APK,篡改一下代码,重新打包,重新生成签名密钥对,签名,这一套攻击,终端用户如何发现呢?就是指这个“可信”~不借助 CA,好像解决不了这个问题?

    实在不行就借助 U 盘了,正文里也说了,算是可以接受得方案
    YGHMXFAL
        6
    YGHMXFAL  
    OP
       Apr 7, 2024
    嗯...不对...国产安卓以后可能不会允许从 U 盘安装 APK...
    luoshuimumu
        7
    luoshuimumu  
       Apr 8, 2024   1
    看得头晕眼花,先不用讲这么多细节,建议简单三句话描述清楚大致的流程和你想问的 #5 改完代码重新打包签名,终端用户没法知道,但是如果你用国产手机并且联了网,自带的应用商店会告诉你安装的是不安全的包,该包签名和应用商店里的安装包的签名不一样
    YGHMXFAL
        8
    YGHMXFAL  
    OP
       Apr 8, 2024
    @luoshuimumu #7

    先说一下我搞这一套流程的动机吧,否则可能难以理解我偏执的那个点,哈哈哈

    我喜欢使用 MX 播放器,而且是自己去 apkmirror 去下载得 APK,去 XDA 论坛下载得 Custom Codec,一切完美

    直到有一天,小米应用商店自作聪明,给我自动静默“更新”到了一个旧版本 MX 播放器...

    就从这个事儿开始,我对国产安卓内置应用商店的印象就非常差,一直都手动下载各种 APK 来安装,或者使用 fdroid 这种开源商店

    所以,现在我对国产安卓内置应用商店的定位就是:你只要能够帮我安装网盘 APP 就行了,然后我从网盘中下载早已准备好地 All-In-One.7Z,解压就能得到我需要地一切 APK,至少得到翻墙 APP 的 APK,出墙了就啥都好说了

    但是由于网盘存在和谐/文件损坏等等意外,所以从网盘下载到本地的任何文件,校验其是否完整是必须滴,这里我使用 SHA512

    说回正题,简单来说,我需要构建一条信任链,链条的根是我打印出来离线保存地几个 HASH 值,因为它只是一张 A4 纸,遭遇赛博破坏地可能性完全没有(相比之下,网盘中的文件,这个可能性大大地有)

    我遇到地障碍是:使用什么 APP 来计算 All-In-One.7Z 的 HASH 呢?这个 APP 本身又怎么校验呢?

    APK 自带地数字签名,它只能证明自己从“签名者”手里到我手里是一致地,但是“签名者≠原始开发者”,谁都可以执行#5 那一套操作,终端用户如何发现这种恶意行为呢?举一个例吧,前一阵子 clash 周边大跑路,很多小白到处求最后一版 APK,这个时候有谁搞了#5 那一套操作,小白如何避免中招呢?你总不能说去国产安卓内置应用商店去安装 clash 吧?

    当然#4 大佬说了,“原始开发者”自身有考虑到这个风险会自己想办法缓解,也可以相信应用商店有严格审核会帮你保证“签名者=原始开发者”

    矛盾就在这里,我对国产安卓内置应用商店不放心(倒不是技术水平,而是道德操守),希望全套校验由自己来手动执行,现在唯一地障碍就是,这个计算 HASH 的 APP,其本身又如何被校验
    unco020511
        9
    unco020511  
       Apr 8, 2024   1
    你篡改了就只能用新的签名去打包,同包名,签名不一样,是没法覆盖安装的.至于用户重新安装,那很正常啊,用户自己从不可信渠道下载应用,就必须要承担这个风险
    YGHMXFAL
        10
    YGHMXFAL  
    OP
       Apr 8, 2024
    @YGHMXFAL #8 其实国产安卓内置应用商店帮你保证“签名者=原始开发者”也就是在其中充当了 CA 的角色

    补充:WIN 上可以找到很多既能够计算 HASH 、又能够校验其自身合法性(因为自带数字签名,和 APK 自带地数字签名不同)且还开源地程序,所以这一套流程在 WIN 上能够跑通,现在想将它复现到 Android 上遇到了麻烦
    rb6221
        11
    rb6221  
       Apr 8, 2024
    @YGHMXFAL #5 首先如果你用篡改的包去覆盖手机上的官方包做升级的话,系统会检测到新包和原包签名不一致,有提醒。你可以理解为浏览器地址栏的小锁上面有个红色警告。
    另外就算你强制覆盖,进去以后运行的时候,开发者也会为了自身的安全,在代码运行逻辑里加一些签名检查流程,防止某些逻辑被篡改和跳过。(也就是我上面说的破解版问题)
    YGHMXFAL
        12
    YGHMXFAL  
    OP
       Apr 8, 2024
    @unco020511 #9 好像是没啥办法,姑且暂定依赖 U 盘了
    YGHMXFAL
        13
    YGHMXFAL  
    OP
       Apr 8, 2024
    @janus77 嗯,这一点我理解了,说得是裸机,全新安装 APP 那种情况
    rb6221
        14
    rb6221  
       Apr 8, 2024   1
    @YGHMXFAL #13 全新安装,只要网络可信,应用商店可信,就没问题啊,这个流程和你自己想的方案在原理上是一样的,最大的风险来自于网络和提供者,你把这两者都解决了,那就 OK 了
    unco020511
        15
    unco020511  
       Apr 8, 2024   1
    @YGHMXFAL #12 我仔细看了你的需求,再准确回答一下你的需求:每个 apk 的签名的 hash 是可以直接用 adb 提取到的,你在可信渠道和非可信渠道获取到的 apk 对比签名的 hash 就可以验证是否是原版的 apk.
    比如:
    apksigner verify --print-certs path/to/your/app.apk
    或者
    keytool -printcert -jarfile path/to/your/app.apk
    About     Help     Advertise     Blog     API     FAQ     Solana     2809 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 56ms UTC 15:30 PVG 23:30 LAX 08:30 JFK 11:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86