概述android
|
認證是用來證實用戶身份合法性的過程,受權是用來證實用戶能夠合法地作哪些事的過程,這兩個過程通常是在服務器端執行的,但也有的APP出於性能提高或用戶體驗等緣由,將其作在客戶端完成,由此致使客戶端繞過等問題。web |
|
安全準則算法
|
|
|
詳細描述安全
|
Item B的典型應用場景是實現自動登陸,用戶登陸認證後在本地存儲用戶的認證token,用戶退出程序時認證token不會被刪除,再次打開程序時可直接攜帶認證token獲取數據,同時爲了保證了足夠的安全性,能夠根據當前終端硬件信息產生獨立密鑰,而後對token進行加密。具體設計參考附錄8。服務器 |
|
備註web安全
|
在本地存儲對稱加密後的用戶口令密文,在登陸時還原出明文也是實現自動登陸的一種可選方案,但其安全性偏低,故在當今已並不是一種主流的作法。性能 |
|
概述this
|
開發人員在移動應用中一般會對敏感數據進行加密處理,可是使用不當有可能讓其保護強度削弱,甚至大打折扣,所以,正確的選擇加解密算法顯得很是重要。編碼 |
|
安全準則加密
|
|
|
詳細描述
|
使用AES128加密算法時,密鑰應同時知足長度(128bit)和複雜度的要求,建議使用安全的隨機數發生器產生安全的密鑰,Sha256哈希算法和AES128對稱加密算法的使用方法請參考附錄1。 |
|
備註
|
注意:在某些不牽涉敏感數據的場景下,不安全的哈希算法仍然是可用的,好比用於校驗文件或數據的完整性。 |
|
概述
|
安全開發能夠大大下降移動應用的安全風險,一樣地,安全的配置和部署可讓風險降到最低。 |
|
安全準則
|
|
|
詳細描述
|
在Activity的onCreate()方法的初始化部分加入如下代碼可用於防截屏: getWindow().addFlags(WindowManager.LayoutParams. FLAG_SECURE); |
|
備註
|
非官方的庫可能被植入惡意代碼,而使用最新版本的庫(非beta版)能夠下降漏洞存在的可能性。 |
|
概述
|
一般一個應用發佈後可能會面臨如下風險: A. 應用被別人解包植入廣告或惡意代碼再重打包發佈。 B. 應用被暴力破解。 C. 應用的核心關鍵代碼邏輯被逆向。 所以,有必要在技術層面採起必定的緩解措施。 |
|
安全準則
|
|
|
詳細描述
|
|
|
備註
|
以上方案參考《Android軟件安全與逆向分析》一書,但只能提供比較基本的保護措施,若是要進一步提升攻擊者的攻擊門檻,建議使用第三方的定製方案。 |
|
概述
|
本項做爲其它移動客戶端項的進一步補充。 |
|
安全準則
|
|
|
詳細描述
|
文件完整性校驗方案(參考附錄9):
|
|
備註
|
存放在外部存儲的文件是可公共訪問的,可能會被其它惡意進程篡改,動態加載這些文件就有可能致使惡意代碼執行。 |
|
概述
|
大部分移動應用並不是一個獨立的單機程序,須要在服務器的支撐下完成一系列的功能,而服務器通常是以web API、web service等方式爲移動客戶端提供服務,所以,也一樣存在web應用的安全問題,而這部分問題牽涉面廣而複雜,沒法在單獨的item內進行描述,可參考《web安全開發指南》 |
|
安全準則
|
請參考《web安全開發指南》 |
|
詳細描述
|
||
備註
|
|
if((getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0){
System.exit(1);//使程序強制退出
}
注意:使用此方法時必須預先在AndroidManifest.xml設置android:debuggable=」false」,攻擊者要嘗試調試應用時頗有可能去修改該參數,於是此手法可用於作動態反調試檢測。
if(android.os.Debug.isDebuggerConnected()){
System.exit(1);
}
public class getSign {
public static int getSignature(PackageManager pm , String packageName){
PackageInfo pi = null;
int sig = 0;
Signature[]s = null;
try{
pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
s = pi.signatures;
sig = s[0].hashCode();//s[0]是簽名證書的公鑰,此處獲取hashcode方便對比
}catch(Exception e){
handleException();
}
return sig;
}
}
主程序代碼參考:
pm = this.getPackageManager();
int s = getSign.getSignature(pm, "com.hik.getsinature");
if(s != ORIGNAL_SGIN_HASHCODE){//對比當前和預埋簽名的hashcode是否一致
System.exit(1);//不一致則強制程序退出
}
private boolean checkcrc(){
boolean checkResult = false;
long crc = Long.parseLong(getString(R.string.crc));//獲取字符資源中預埋的crc值
ZipFile zf;
try{
String path = getApplicationContext().getPackageCodePath();//獲取apk安裝路徑
zf = new ZipFile(path);//將apk封裝成zip對象
ZipEntry ze = zf.getEntry("classes.dex");//獲取apk中的classes.dex
long CurrentCRC = ze.getCrc();//計算當前應用classes.dex的crc值
if(CurrentCRC != crc){//crc值對比
checkResult = true;
}
}catch(IOException e){
handleError();
checkResult = false;
}
return checkResult;
}
注意:一旦修改源代碼,從新編譯後classes.dex的CRC值就會變掉,所以正確的CRC值置不可以預置在代碼中,能夠考慮置放在資源文件中。