android 4.4 授信安装
来源:互联网 发布:java aes加密解密算法 编辑:程序博客网 时间:2024/04/28 13:38
android4.4 授信安装,只能安装指定证书的应用
如果打开设置–>安全–>验证应用 后,系统在安装apk时默认会检查系统中是否存在符合条件的广播接受者,然后发送apk信息。这个广播接受者可以完成验证安装。
我们的思路是在系统中新建一个ContentResolver 用于存储系统中支持的应用证书信息。apk安装的时候会查询并校验apk。确定是否同意安装。
packageManagerService–>handleStartCopy函数检查符合条件的Receiver,并发送信息,而我们会增加verification.putExtra(“pkg_path”,mPackageURI.getPath());主要用于接受端解析apk,获取证书信息并校验。
Receiver端:
AndroidManifest.xml如下:
<receiver android:name=".verificationApp"> <intent-filter> <action android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION"/> <data android:mimeType="application/vnd.android.package-archive"/> </intent-filter> </receiver>
在verificationApp 中:
如果同意安装调用:
mPm = context.getPackageManager(); mPm.verifyPendingInstall(id, PackageManager.VERIFICATION_ALLOW);
不同意安装:
mPm.verifyPendingInstall(id, PackageManager.VERIFICATION_REJECT);
授信安装的思路大致如此,除了上面的这些,剩下的就只有添加证书的应用程序,已经存储证书的provider了。
证书存储:
package com.provider.pkgShaProvider;import android.content.ContentProvider;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.security.MessageDigest;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * Created by haozhenghui on 16/8/25. */public class pkgShaProvider extends ContentProvider { private String DB_name="pkgSha1.db3"; private String my_table="allowApp"; final String TAG="pkgSha1Provider"; private final String cerPath="/system/planCer/"; private List<cerCls> cerList=new ArrayList<cerCls>(); SQLiteDatabase pkgDb; @Override public boolean onCreate() { cerList=ReadSystemCerFile(); pkgDb=this.getContext().openOrCreateDatabase(DB_name, Context.MODE_PRIVATE, null); pkgDb.execSQL("create table if not exists "+my_table+"(_id INTEGER PRIMARY KEY AUTOINCREMENT, sha1 TEXT NOT NULL,owner TEXT," + "announcer TEXT," + "SerialNum TEXT," + "MD5 TEXT," + "SHA256 TEXT," + "AlgorithmName TEXT," + "versionNum TEXT," + "system TEXT" + ")"); for (int i=0;i<cerList.size();i++){ cerCls cer=cerList.get(i); if (!lineIsExist(pkgDb,my_table,"sha1",cer.SHA1)){ insertLine(pkgDb,my_table,cer); } } return true; } public void insertLine(SQLiteDatabase pkgDb,String my_table,cerCls cer){ ContentValues values=new ContentValues(); values.put("sha1",cer.SHA1); values.put("owner",cer.owner); values.put("announcer",cer.announcer); values.put("SerialNum",cer.SerialNum); values.put("MD5",cer.MD5); values.put("SHA256",cer.SHA256); values.put("AlgorithmName",cer.AlgorithmName); values.put("versionNum",cer.versionNum); values.put("system",cer.system); pkgDb.insert(my_table,null,values); } public boolean lineIsExist(SQLiteDatabase pkgdb,String tab_name,String srcName,String distName){ Cursor cursor=pkgdb.query(tab_name, null, null, null, null, null,null); cursor.moveToFirst(); for(int i=0; i<cursor.getCount(); i++){ int index = cursor.getColumnIndexOrThrow(srcName); String src = cursor.getString(index); if (src.equals(distName)){ return true; } cursor.moveToNext(); } return false; } public List<cerCls> ReadSystemCerFile(){ List<cerCls> myCerList=new ArrayList<cerCls>(); File file=new File(cerPath); File[] subFile = file.listFiles(); for (int i=0;i<subFile.length;i++){ if(subFile[i].isFile()){ try { cerCls cer=ReadX509CerFile(subFile[i]); cer.system="true"; myCerList.add(cer); } catch (Exception e) { e.printStackTrace(); } } } return myCerList; } public cerCls ReadX509CerFile(File file) throws Exception{ cerCls cerC=new cerCls(); try { InputStream inStream = new FileInputStream(file); // 创建X509工厂类 CertificateFactory cf = CertificateFactory.getInstance("X.509"); //CertificateFactory cf = CertificateFactory.getInstance("X509"); // 创建证书对象 X509Certificate oCert = (X509Certificate) cf .generateCertificate(inStream); inStream.close(); SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd"); String info = null; // 获得证书版本 info = String.valueOf(oCert.getVersion()); cerC.versionNum=info; // 获得证书序列号 info = oCert.getSerialNumber().toString(16); cerC.SerialNum=info; // 获得证书有效期 Date beforedate = oCert.getNotBefore(); info = dateformat.format(beforedate);// System.out.println("证书生效日期:" + info); Date afterdate = oCert.getNotAfter(); info = dateformat.format(afterdate);// System.out.println("证书失效日期:" + info); // 获得证书主体信息 info = oCert.getSubjectDN().getName(); cerC.owner=info; // 获得证书颁发者信息 info = oCert.getIssuerDN().getName(); cerC.announcer=info; // 获得证书签名算法名称 info = oCert.getSigAlgName(); cerC.AlgorithmName=info;// PublicKey pk = oCert.getPublicKey();// System.out.println("pk:"+pk.toString()); MessageDigest md= MessageDigest.getInstance("SHA1"); byte[] publicKey=md.digest(oCert.getEncoded()); String hexString=byte2HexFormatted(publicKey);// System.out.println(hexString); cerC.SHA1=hexString; } catch (Exception e) { System.out.println("解析证书出错!"); e.printStackTrace(); } return cerC; } public String byte2HexFormatted(byte[] arr){ StringBuilder str=new StringBuilder(arr.length * 2); for (int i=0;i<arr.length;i++){ String h=Integer.toHexString(arr[i]); int l=h.length(); if (l==1){ h="0"+h; } if (l>2){ h=h.substring(l-2, l); } str.append(h.toUpperCase()); if (i<arr.length-1){ str.append(':'); } } return str.toString(); } @Override public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) { Cursor c = pkgDb.query(my_table, null, null, null, null, null,null); return c; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues contentValues) { pkgDb.insert(my_table,null,contentValues); return null; } @Override public int delete(Uri uri, String s, String[] strings) { pkgDb.delete(my_table,s,strings); return 0; } @Override public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { return 0; }}
读取本地证书:
package com.android.settings.verifyapp;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.security.MessageDigest;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * Created by haozhenghui on 16-8-30. */public class ReadCerFile { private final String TAG="ReadCerFile"; public List<cerCls> ReadUserCerFile(String path) { List<cerCls> myCerList = new ArrayList<cerCls>(); File file = new File(path); File[] subFile = file.listFiles(); for (int i = 0; i < subFile.length; i++) { if (subFile[i].isFile()) { try { cerCls cer = ReadX509CerFile(subFile[i]); cer.system = "false"; myCerList.add(cer); } catch (Exception e) { e.printStackTrace(); } } } return myCerList; } public cerCls readX509CerFileFromUser(String path){ Log.d(TAG,"path:"+path); File file=new File(path); if (file.isFile()){ try { cerCls cer=ReadX509CerFile(file); cer.system="false"; return cer; } catch (Exception e) { e.printStackTrace(); } } Log.e(TAG,"not file"); return null; } public cerCls ReadX509CerFile(File file) throws Exception { cerCls cerC = new cerCls(); try { InputStream inStream = new FileInputStream(file); // 创建X509工厂类 CertificateFactory cf = CertificateFactory.getInstance("X.509"); //CertificateFactory cf = CertificateFactory.getInstance("X509"); // 创建证书对象 X509Certificate oCert = (X509Certificate) cf .generateCertificate(inStream); inStream.close(); SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd"); String info = null; // 获得证书版本 info = String.valueOf(oCert.getVersion()); cerC.versionNum = info; // 获得证书序列号 info = oCert.getSerialNumber().toString(16); cerC.SerialNum = info; // 获得证书有效期 Date beforedate = oCert.getNotBefore(); info = dateformat.format(beforedate);// System.out.println("证书生效日期:" + info); Date afterdate = oCert.getNotAfter(); info = dateformat.format(afterdate);// System.out.println("证书失效日期:" + info); // 获得证书主体信息 info = oCert.getSubjectDN().getName(); cerC.owner = info; // 获得证书颁发者信息 info = oCert.getIssuerDN().getName(); cerC.announcer = info; // 获得证书签名算法名称 info = oCert.getSigAlgName(); cerC.AlgorithmName = info;// PublicKey pk = oCert.getPublicKey();// System.out.println("pk:"+pk.toString()); MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] publicKey = md.digest(oCert.getEncoded()); String hexString = byte2HexFormatted(publicKey);// System.out.println(hexString); cerC.SHA1 = hexString; } catch (Exception e) { System.out.println("解析证书出错!"); e.printStackTrace(); } return cerC; } public String byte2HexFormatted(byte[] arr) { StringBuilder str = new StringBuilder(arr.length * 2); for (int i = 0; i < arr.length; i++) { String h = Integer.toHexString(arr[i]); int l = h.length(); if (l == 1) { h = "0" + h; } if (l > 2) { h = h.substring(l - 2, l); } str.append(h.toUpperCase()); if (i < arr.length - 1) { str.append(':'); } } return str.toString(); }}
0 0
- android 4.4 授信安装
- 微信android混淆打包减少安装包大小
- Android中判断QQ、微信是否安装的方法
- Android 检测微信或者微博是否安装
- Android:判断手机是否安装了QQ或者微信
- android 友盟分享 判断QQ,微信是否安装
- Android 判断手机是否安装QQ或者微信
- Android判断手机是否安装微信(总结)
- Android 微信支付 判断用户手机是否安装微信客户端
- Ubuntu安装飞信
- 安装飞信
- ubuntu 安装飞信
- ubuntu 安装飞信
- 飞信安装
- 安装飞信
- Ubuntu 飞信安装
- Linux安装飞信
- ubuntu 安装飞信
- 关于.NET的单元测试
- C# sha1加密
- qcril接口函数
- 新型非易失性存储器作为交换分区的研究(能耗与性能的提升)
- LEAK: ByteBuf.release() was not called before it's garbage-collected. Enable advanced leak reporting
- android 4.4 授信安装
- libuv之线程池的坑,注意避免
- jquery - 滚动div到头部的距离
- dom4j解析xml简单列子
- createContextualFragment 方法
- 悬崖勒马之三年编码的反省
- 今天我要开博客了
- 搭建自己域名的hexo框架next风格的博客
- android window flags