編輯:關於Android編程
android4.4 授信安裝,只能安裝指定證書的應用
如果打開設置–>安全–>驗證應用 後,系統在安裝apk時默認會檢查系統中是否存在符合條件的廣播接受者,然後發送apk信息。這個廣播接受者可以完成驗證安裝。
我們的思路是在系統中新建一個ContentResolver 用於存儲系統中支持的應用證書信息。apk安裝的時候會查詢並校驗apk。確定是否同意安裝。
packageManagerService–>handleStartCopy函數檢查符合條件的Receiver,並發送信息,而我們會增加verification.putExtra(“pkg_path”,mPackageURI.getPath());主要用於接受端解析apk,獲取證書信息並校驗。
Receiver端:
AndroidManifest.xml如下:
在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 cerList=new ArrayList();
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 ReadSystemCerFile(){
List myCerList=new ArrayList();
File file=new File(cerPath);
File[] subFile = file.listFiles();
for (int i=0;i2){
h=h.substring(l-2, l);
}
str.append(h.toUpperCase());
if (i讀取本地證書:
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 ReadUserCerFile(String path) {
List myCerList = new ArrayList();
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 自定義View總結
Paint與Canvas下面先說下Paint的基本設置函數:paint.setAntiAlias(true);//抗鋸齒功能paint.setColor(Color.RE
解決:Android4.3鎖屏界面Emergency calls only - China Unicom與EMERGENCY CALL語義重復
從圖片中我們可以看到,這裡在語義上有一定的重復,當然這是谷歌的原始設計。這個問題在博客上進行共享從表面上來看著實沒有什麼太大的意義,不過由於Andro
android 事件分發機制(圖文詳解)
在Android開發中,事件分發機制是一塊Android比較重要的知識體系,了解並熟悉整套的分發機制有助於更好的分析各種點擊滑動失效問題,更好去擴展控件的事件功能和開發自
Android仿美團下拉菜單(商品選購)實例代碼
美團電商應用平台大家使用非常頻繁,下面小編通過本文給大家介紹電商應用平台中常用的選擇類別下拉列表的實現。先給大家展示下效果圖:一、下拉列表的實現其實實現方法有很多,這時實