Android使用特殊权限的一种代码实现

android编程中有时候需要用到一些特殊的权限,这些权限正常情况下是不对普通的第三方app开发商开放的。举个例子 WRITE_SECURE_SETTINGS,android sdk文档是这么解释的
   
   
public static final String WRITE_SECURE_SETTINGS
 
Added in API level 3
Allows an application to read or write the secure system settings.
 
Not for use by third-party applications.
 
Constant Value: "android.permission.WRITE_SECURE_SETTINGS"
我自己的应用(本文中成为MyApk),需要使用这类权限时,可以采用商务谈判的方式,将使用这部分的代码独立出来放在另外一个apk(在本文中,我将它称为Addon)中,将这些该Addon让rom厂商签名。MyApk和Addon之间的通讯就是普通的app之间的通讯了,本文介绍的例子的采用的是aidl的方式。

Addon Service在manifest.xml中的声明
   
   
<service android:name="com.jacksonke.remoteService.BshService">
<intent-filter>
<action android:name="com.jacksonke.remoteService.addon" />
</intent-filter>
</service>
MyApk连接Service的代码
   
   
getActivity().getApplicationContext()
.bindService(new Intent(
"com.jacksonke.remoteService.addon"),
this, Context.BIND_AUTO_CREATE);

按照一般的aidl的进程间通讯实现的话,会存在一定的问题,即其它任意app只要知道intent-action " com.jacksonke.remoteService.addon ",都可以和Addon进行通讯。这就要求Addon对连接请求做一定的判断,我这边是采取一定的防御措施,本文介绍的防御措施,判断调用者apk的数字签名序列号是否满足条件。满足的话才能使用Service提供的内容。
   
   
BigInteger myBigInteger = new BigInteger("3d40fee9", 16);
// 所有者: CN=Android Debug, O=Android, C=US
// 发布者: CN=Android Debug, O=Android, C=US
// 序列号: 5bac446d
// 有效期开始日期: Wed Apr 09 18:43:39 CST 2013, 截止日期: Fri Apr 01 18:43:39 CST
// 2044
// 证书指纹:
// MD5: 34:DE:33:0A:FD:E4:2E:21:58:9F:8A:57:0E:80:05:20
// SHA1: B0:23:B2:20:03:33:82:70:21:D2:0B:8C:22:68:F8:D8:F4:54:A5:B9
// SHA256: 53:28:F6:92:A7:F8:83:D6:9C:54:B6:2B:EC:C8:78:31:B9:3D:93:02:EC:
// 39:65:C8:E1:F6:DB:3C:26:A2:B7:2C
// 签名算法名称: SHA256withRSA
// 版本: 3
//
// 扩展:
//
// #1: ObjectId: 2.5.29.14 Criticality=false
// SubjectKeyIdentifier [
// KeyIdentifier [
// 0000: 75 8F 78 E1 8A E9 B4 CB 79 3D 58 9C 63 F9 88 1C u.x.....y=X.c...
// 0010: 03 02 25 86 ..%.
// ]
// ]
BigInteger myBigInteger2 = new BigInteger("5bac446d", 16);
boolean callerValide = false;
 
boolean checkCallValide(){
String packageName =getPackageManager().getNameForUid(Binder.getCallingUid());
AddonLog.log("caller name =" + packageName);
 
try {
PackageInfo pi = getApplicationContext().getPackageManager().getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
try {
X509Certificate certificate = X509Certificate.getInstance(pi.signatures[0].toByteArray());
BigInteger serialBigInteger = certificate.getSerialNumber();
AddonLog.log("" + serialBigInteger.toString(16));
if (_debug){
return true;
}
else{
if (serialBigInteger.compareTo(myBigInteger2) == 0
|| serialBigInteger.compareTo(myBigInteger) == 0){
callerValide = true;
return true;
}
else{
callerValide = false;
return false;
}
}
} catch (CertificateException e) {
e.printStackTrace();
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
callerValide = false;
return false;
}

myBigInteger2的值就是MyApk数字签名的序列号,可以通过以下方式获取
1. 将apk后缀改为zip,用WinRAR打开,将META-INF/CERT.RSA解压出来,比如说解压到D:\CERT.RSA
2. 命令行底下用
    D:\android\project>keytool -printcert -file "D:\CERT.RSA"
    就能看到序列号了


题外话
showPermission()函数的功能是打印Addon和MyApk是否拥有某些权限。可以验证Addon是否获取了特殊权限。
   
   
void showPermissionInfo(){
int myPid = Process.myPid();
int myUid = Process.myUid();
AddonLog.log("myPid=" + myPid + " myUid="+ myUid);
AddonLog.log("Test if this process has permission WRITE_SECURE_SETTINGS");
if (checkPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, myPid, myUid)
== PackageManager.PERMISSION_GRANTED){
AddonLog.log("-------------yes");
}
else{
AddonLog.log("-------------no");
}
AddonLog.log("BinderCallingPid =" + Binder.getCallingPid());
AddonLog.log("BinderCallingUid =" + Binder.getCallingUid());
AddonLog.log("Test if BinderCalling has permission WRITE_SECURE_SETTINGS");
if (checkPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, Binder.getCallingPid(), Binder.getCallingUid())
== PackageManager.PERMISSION_GRANTED){
AddonLog.log("-----------------yes.");
}
else{
AddonLog.log("-----------------no.");
}
}
结果如下


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值