android 4.4 授信安装

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();

    }
}

猜你喜欢

转载自blog.csdn.net/haozhenghui10/article/details/52386023
4.4