添加knownSigner后自定义安全ContentProvider抛出SecurityException问题求助
问题背景
两个使用不同签名密钥的应用,尝试通过配置signature|knownSigner级别的权限实现ContentProvider的安全访问。仅配置权限名称时ContentProvider可正常工作,但添加knownCerts配置后触发权限拒绝错误:
java.lang.SecurityException: Permission Denial: opening provider com.example.myapplication.CustomProvider from ProcessRecord{c4924bb 23886:package.name/u0a701} (pid=23886, uid=10701) requires com.example.myapplication.READ_PERMISSION or com.example.myapplication.READ_PERMISSION
权限配置:
<permission android:name="com.example.myapplication.READ_PERMISSION" android:protectionLevel="signature|knownSigner" android:knownCerts="@raw/known_certs" tools:targetApi="s" />
known_certs.xml内容:
<?xml version="1.0" encoding="utf-8"?> <certificates> <certificate> <alias>androiddebugkey</alias> <sha1>SHA1 CODE</sha1> </certificate> </certificates>
排查步骤
校验SHA-1指纹格式与准确性
- SHA-1必须是大写、冒号分隔的格式(例如
AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD),不能使用小写、无冒号的字符串或带有多余空格的内容。 - 用命令获取访问方App的准确签名指纹:
确保keytool -list -v -keystore 访问方签名文件路径.jksknown_certs.xml中的SHA-1与该输出完全一致。
- SHA-1必须是大写、冒号分隔的格式(例如
确认权限规则逻辑
signature|knownSigner的生效逻辑是:调用方要么与权限定义方(ContentProvider所在App)签名完全一致(signature规则),要么签名指纹存在于knownCerts列表中(knownSigner规则)。如果两个App签名不同,必须确保访问方的指纹已正确加入known_certs.xml。检查文件配置与引用
- 确保
known_certs.xml放置在res/raw/目录下,文件名无拼写错误(区分大小写)。 - 权限标签中的
android:knownCerts="@raw/known_certs"引用路径正确,无大小写或拼写错误。
- 确保
验证系统版本兼容性
knownSigner是Android 12(API 31)新增的权限级别,仅在API 31及以上版本设备上生效。如果测试设备系统版本低于Android 12,该配置会被忽略,权限会降级为signature级别,此时签名不同的访问方会被拒绝。确认访问方App的权限声明
访问方的AndroidManifest.xml中必须显式声明该权限:<uses-permission android:name="com.example.myapplication.READ_PERMISSION" />即使依赖
knownSigner规则,未声明权限仍会触发权限拒绝。移除可选的alias字段
<alias>字段为可选配置,部分场景下可能因别名不匹配导致验证失败。可以尝试删除<alias>androiddebugkey</alias>,仅保留<sha1>标签内容,系统主要校验的是指纹信息。
内容的提问来源于stack exchange,提问作者Masoud Kardani

