You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Play重签名后AIDL跨应用signature权限绑定报错解决

问题现象

应用运行时抛出异常:

java.lang.RuntimeException: Unable to create application XXX: java.lang.SecurityException: Not allowed to bind to service Intent

故障场景为两个应用通过AIDL实现跨进程通信:服务端应用提供AIDL接口实现,自定义应用权限,对外服务设置为可导出、配置意图过滤器并绑定上述自定义权限;客户端应用声明使用该权限,主动绑定服务端服务。

相关配置

服务端应用Manifest配置

<manifest
  package="com.my.server">
  ...
  <permission
    android:name="com.my.app_permission"
    android:protectionLevel="signature" />

  <application
    ...
    
    <service
        android:name="com.my.MyService"
        android:exported="true"
        android:permission="com.my.app_permission">
        <intent-filter>
            <action android:name="my_aidl" />
        </intent-filter>
    </service>
    
    
  </application>
</manifest>

客户端应用Manifest配置

<manifest
  package="com.my.client">
  ...

  <queries>
    <package android:name="com.my.server" />
  </queries>

  <uses-permission android:name="com.my.app_permission"/>

  <application
    android:name=".App"
    ...
    
  </application>
</manifest>

客户端Application绑定逻辑

class App: Application() {
  override fun onCreate() {
    super.onCreate()
    if (serverAppInstalled()) {
      bindService(
        Intent().apply {
          action = "my_aidl"
          package = "com.my.server"
        },
        serviceConnection,
        Context.BIND_AUTO_CREATE
      )
    }
  }

  ...
}

注:示例代码中onCreate缺少override修饰符和super调用,属于笔误,实际运行需补全。

测试验证结果
  • 每次测试前完全卸载设备上的两个相关应用,安装顺序固定为先装服务端、再装客户端
  • 本地Debug构建包、使用同一签名密钥签署的本地Release APK均可正常运行
  • 两个应用的AAB包上传至Google Play内部测试渠道后,运行时固定抛出上述SecurityException异常
  • 移除自定义权限的protectionLevel配置后,跨进程绑定功能可正常运行
  • 根因确认:Google Play基于上传的AAB包针对不同设备配置拆分生成对应APK时,会执行重签名操作;若两个应用未配置共享签名密钥,重签名后两个应用签名不一致,无法通过signature级别的系统权限校验。
可行解决方案

按改造成本从低到高排序:

  1. 配置Play应用签名密钥共享
    两个应用归属同一Google Play开发者账号时,可在Play管理中心将两个应用加入同一签名组,共享同一个应用签名密钥,保证Play重签名后两个应用签名一致,原有signature级别权限逻辑无需任何修改即可正常运行,是改造成本最低的方案。

  2. 替换系统权限校验为自定义签名校验
    放弃Manifest中配置的signature级别权限控制,在服务端的Service生命周期中自行做调用方合法性校验:

    • 移除服务端Manifest中service节点的android:permission属性,移除自定义的signature级别权限声明,移除客户端Manifest中对应的uses-permission声明
    • 服务端重写Service的onBind方法,通过Binder.getCallingUid()获取调用方uid,再通过PackageManager.getPackagesForUid()、PackageManager.getPackageInfo()获取调用方包名和签名信息
    • 校验调用方包名是否为约定的客户端包名,同时比对调用方签名哈希是否和预先内置的、客户端在Play渠道发布后的正式签名哈希完全一致,校验通过再返回IBinder实例,否则直接返回null拒绝绑定
      该方案完全不依赖系统的signature权限机制,不受任何应用商店重签名逻辑影响,兼容性最强,注意内置的签名哈希需要做代码混淆和字符串加密,避免被反编译篡改。
  3. 适配Android 11+的签名权限已知签署者配置
    如果应用仅需适配Android 11(API 30)及以上版本,可在服务端自定义权限声明时增加knownCertificates属性,直接写入客户端正式签名的证书摘要,系统在做权限校验时会直接匹配证书摘要,不再要求两个应用必须由同一个密钥签名,不过该方案对低版本Android不兼容,适用场景有限。

注意:不要为了临时解决问题直接移除权限校验、或者将权限protectionLevel设为normal,会导致服务被任意第三方应用随意绑定,存在严重的安全风险。

内容的提问来源于stack exchange,提问作者Dmytro Batyuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:57:14