V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
YGHMXFAL
V2EX  ›  Android

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

  •  
  •   YGHMXFAL · 241 天前 · 5814 次点击
    这是一个创建于 241 天前的主题,其中的信息可能已经有所发展或是发生改变。

    备份阶段:

    ●将常用软件+密码库+其它资源等等加密打包到①[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 条回复    2024-04-08 10:33:26 +08:00
    YGHMXFAL
        1
    YGHMXFAL  
    OP
       241 天前
    文末的“注”漏了😂😂😂“我选择了[git for windows]”
    linhua
        2
    linhua  
       241 天前   ❤️ 1
    安卓也自带 SHA***SUM

    adb shell

    130|HWEML:/ $ sha

    sha1sum sha224sum sha256sum sha384sum sha512sum
    YGHMXFAL
        3
    YGHMXFAL  
    OP
       241 天前
    @linhua

    嗯,通过 ADB 访问 SHELL,

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

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

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


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

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

    实在不行就借助 U 盘了,正文里也说了,算是可以接受得方案
    YGHMXFAL
        6
    YGHMXFAL  
    OP
       241 天前
    嗯...不对...国产安卓以后可能不会允许从 U 盘安装 APK...
    luoshuimumu
        7
    luoshuimumu  
       241 天前   ❤️ 1
    看得头晕眼花,先不用讲这么多细节,建议简单三句话描述清楚大致的流程和你想问的 #5 改完代码重新打包签名,终端用户没法知道,但是如果你用国产手机并且联了网,自带的应用商店会告诉你安装的是不安全的包,该包签名和应用商店里的安装包的签名不一样
    YGHMXFAL
        8
    YGHMXFAL  
    OP
       241 天前
    @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  
       241 天前   ❤️ 1
    你篡改了就只能用新的签名去打包,同包名,签名不一样,是没法覆盖安装的.至于用户重新安装,那很正常啊,用户自己从不可信渠道下载应用,就必须要承担这个风险
    YGHMXFAL
        10
    YGHMXFAL  
    OP
       241 天前
    @YGHMXFAL #8 其实国产安卓内置应用商店帮你保证“签名者=原始开发者”也就是在其中充当了 CA 的角色

    补充:WIN 上可以找到很多既能够计算 HASH 、又能够校验其自身合法性(因为自带数字签名,和 APK 自带地数字签名不同)并且还开源地程序,所以这一套流程在 WIN 上能够跑通,现在想将它复现到 Android 上遇到了麻烦😁😁
    janus77
        11
    janus77  
       241 天前
    @YGHMXFAL #5 首先如果你用篡改的包去覆盖手机上的官方包做升级的话,系统会检测到新包和原包签名不一致,有提醒。你可以理解为浏览器地址栏的小锁上面有个红色警告。
    另外就算你强制覆盖,进去以后运行的时候,开发者也会为了自身的安全,在代码运行逻辑里加一些签名检查流程,防止某些逻辑被篡改和跳过。(也就是我上面说的破解版问题)
    YGHMXFAL
        12
    YGHMXFAL  
    OP
       241 天前
    @unco020511 #9 好像是没啥办法,姑且暂定依赖 U 盘了
    YGHMXFAL
        13
    YGHMXFAL  
    OP
       241 天前
    @janus77 嗯,这一点我理解了,说得是裸机,全新安装 APP 那种情况
    janus77
        14
    janus77  
       241 天前   ❤️ 1
    @YGHMXFAL #13 全新安装,只要网络可信,应用商店可信,就没问题啊,这个流程和你自己想的方案在原理上是一样的,最大的风险来自于网络和提供者,你把这两者都解决了,那就 OK 了
    unco020511
        15
    unco020511  
       240 天前   ❤️ 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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6018 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 02:08 · PVG 10:08 · LAX 18:08 · JFK 21:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.