android 4.4 授信安装

原创 2016年08月31日 16:02:58

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

    }
}

相关文章推荐

Android Action

BroadcastReceiver_ACTION: ACTION_AIRPLANE_MODE_CHANGED "android.intent.action.AIRPLANE_MODE"  --用户切...
  • lalate
  • lalate
  • 2016年05月05日 11:49
  • 1733

Android 4.4+ 拦截短信和发送短信

  • 2016年06月28日 15:00
  • 1.2MB
  • 下载

VirtualBox安裝 Android-x86 4.4

1、下载好Android-x86 4.4镜像文件 链接:http://pan.baidu.com/s/1yiG8Y 密码:b3r3 这是笔者用的光盘镜像文件,读者也可以到其他地方下载使用。 2、...

Android 4.4(KitKat)中apk包的安装过程

其实对于apk包的安装,4.4和之前版本没大的差别。Android中app安装主要有以下几种情况:系统启动时安装,adb命令安装,Google Play上下载安装和通过PackageInstaller...

android4.4(kitkat),如何让APP可以直接写入SMS短信

以下代码的修改是针对android平台研发的,另外如果没有系统源码的情况下,通过逆向修改ROM中的对应文件,也是可以做到的。 之所以有这样需求,是因为假如是你自己的ROM,需要对自己的某个APP...

Android4.4以后第三方应用无法删除短信的解决方案

一、概述最近测试提交了一个bug:用我们的应用删除Android5.0手机上的短信失败。二、原因分析在google查阅后得知:Android为了防止第三方软件拦截短信和偷发短信吸费,在android4...

android4.4的短信发送流程

android4.4 原生代码信息分析之短信发送流程

Android4.4后短信机制的变化

原文:http://www.zhihu.com/question/22111420/answer/46388662 4.4 之前: 新接收短信广播 SMS_RECEIVED_ACT...

关于android4.4及以上版本无法恢复还原短信的问题记录与解决

android4.4及以上版本因权限问题导致短信无法写入短信数据库或恢复的一种解决办法,希望能帮助同样遇到此问题的人,避免再次踩坑...
  • pengbs
  • pengbs
  • 2015年10月11日 13:40
  • 1321

android 4.4 设置默认短信 和来电短信拒接

http://blog.csdn.net/subaohao/article/details/39368961 ACTION_RESPONSE_VIA_MESSAG...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 4.4 授信安装
举报原因:
原因补充:

(最多只允许输入30个字)