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
原创粉丝点击