1. 程式人生 > >安卓 assets配置檔案加密

安卓 assets配置檔案加密

安卓應用的中配置檔案資訊,為了防止篡改,一般不以明文的形式進行儲存。

配置資訊示例:

配置加密後:

程式碼中配置資訊的讀取:


import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

import android.content.Context;
import android.util.Log;


/** AssetProperty.java: 讀取assets目錄中的配置檔案資訊----- 2018-2-27 下午8:08:10 scimence */
public class AssetProperty
{
	// 示例:
	private void Example()
	{
		// assets目錄下的檔案如: assets/payconfig.txt
		// #檔案內容:
		// ShowAlipay=true
		// ShowWeChat=true
		
		AssetProperty config = new AssetProperty(context, "payconfig.txt");
		String ShowAlipay = config.getConfig("ShowAlipay", "true");			// 讀取配置資訊
		
		// 備註:直接在檔案目錄下新增檔案,getAssets().open()可能會報錯: java.io.FileNotFoundException: payconfig.txt
		// 在assets中新增配置檔案,需選中assets資料夾(右鍵)-> New -> File -> 輸入檔名(payconfig.txt)-> Finish
	}
	
	// -------------------------------
	
	String filepath = "";	// assets目錄下的檔案如: assets/payconfig.txt
	Context context;
	Properties prop = null;
	
	/** 建立AssetProperty */
	public AssetProperty(Context context, String filepath)
	{
		this.context = context;
		this.filepath = filepath;
		
		// if (prop == null) prop = getAssetsProperty(context, filepath);
		if (prop == null) prop = getAssetsPropertyEncrypt(context, filepath);
	}
	
	/** 讀取AssetProperty中的配置資訊 */
	public String getConfig(String name, String defval)
	{
		if (prop == null)
			return defval;
		else return prop.getProperty(name, defval);
	}
	
	/** 讀取Assest資料夾下資源,返回Properties */
	public static Properties getAssetsProperty(Context context, String filepath)
	{
		try
		{
			Properties prop = new Properties();
			InputStreamReader reader = new InputStreamReader(context.getAssets().open(filepath), "UTF-8");
			prop.load(reader);
			
			reader.close();
			return prop;
		}
		catch (Exception e)
		{
			Log.e("AssetProperty", e.toString());
		}
		return null;
	}
	
	/** 讀取Assest資料夾下資源,返回Properties。若為加密資料則自動解密 */
	public static Properties getAssetsPropertyEncrypt(Context context, String filepath)
	{
		try
		{
			// 讀取assets資料
			InputStream inputStream = context.getAssets().open(filepath);
			String data = TypeTool.InputStreamToString(inputStream);
			inputStream.close();
			
			// assets資料解密邏輯
			if (Encrypt.isEncrypt(data)) data = Encrypt.Encryption(data.substring(5), -65537);		// 解密資料
				
			// ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());
			// InputStreamReader reader = new InputStreamReader(in);
			InputStreamReader reader = TypeTool.StringToInputStreamReader(data);
			
			Properties prop = new Properties();
			prop.load(reader);
			
			reader.close();
			
			return prop;
		}
		catch (Exception e)
		{
			Log.e("AssetProperty", e.toString());
		}
		return null;
	}
}

TypeTool.java


package com.ltsdk.thumbsup.funchtion;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;


/** TypeTool.java:資料型別相互轉化工具類 ----- 2018-10-23 上午10:08:54 scimence */
public class TypeTool
{
	/** Byte -> String */
	public static String ByteToString(byte[] bytes)
	{
		return new String(bytes);
	}
	
	/** String -> Byte */
	public static byte[] StringToByte(String data)
	{
		return data.getBytes();
	}
	
	/** Byte -> InputStream */
	public static final InputStream ByteToInputStream(byte[] bytes)
	{
		return new ByteArrayInputStream(bytes);
	}
	
	/** InputStream -> Byte */
	public static final byte[] InputStreamToByte(InputStream in)
	{
		byte[] bytes = {};
		
		try
		{
			ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
			byte[] data = new byte[1024];
			int count = 0;
			while ((count = in.read(data, 0, 1024)) > 0)
			{
				byteOutStream.write(data, 0, count);
			}
			
			bytes = byteOutStream.toByteArray();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		return bytes;
	}
	
	/** InputStream -> String */
	public static String InputStreamToString(InputStream in)
	{
		String data = "";
		
		byte[] bytes = InputStreamToByte(in);
		data = new String(bytes);
		
		return data;
	}
	
	/** String -> InputStream */
	public static InputStream StringToInputStream(String data)
	{
		byte[] bytes = data.getBytes();
		InputStream inputstream = ByteToInputStream(bytes);
		return inputstream;
	}
	
	/** String -> InputStreamReader */
	public static InputStreamReader StringToInputStreamReader(String data)
	{
		byte[] bytes = data.getBytes();
		InputStream inputstream = ByteToInputStream(bytes);
		InputStreamReader reader = new InputStreamReader(inputstream);
		return reader;
	}
	
}

Encrypt.java


package sci.tools;


/** Encrypt.java: 對字串或檔案進行自定義加解密。
 * 加密字串:Encryption(String str, int change)
 * 解密字串:Encryption(String str, int -change) 
 * 加密byte陣列:Encryption(byte[] bytes, int change) 
 * 解密byte陣列:Encryption(byte[] bytes, int -change) 
 * ----- 2018-10-22 下午5:50:35 scimence */
public class Encrypt
{
	/** 對字串資料進行加解密, change加密、 -chage解密 */
	public static String Encryption(String str, int change)
	{
		if ((str.equals("")) || (str == null)) return "";
		
		byte[] bytes;
		if (change < 0)
			bytes = toBytes(str);
		else bytes = str.getBytes();
		
		Encryption(bytes, change);
		
		if (change < 0)
			str = new String(bytes);
		else str = toHex(bytes);
		
		return str;
	}
	
	/** 對bytes資料進行加密、解密操作, change加密、 -chage解密 */
	public static void Encryption(byte[] bytes, int change)
	{
		short sign = 1;
		if (change < 0)
		{
			sign = -1;
			change *= -1;
		}
		
		int num = 0;
		for (int i = 0; i < bytes.length; i++)
		{
			if (num == 0) num = change;
			
			int tmp = bytes[i] + sign * (num % 3);
			
			if (tmp > 127)
				tmp -= 255;
			else if (tmp < -128) tmp += 255;
			
			bytes[i] = ((byte) tmp);
			num /= 3;
		}
	}
	
	private static String toHex(byte[] B)
	{
		String tmp = "";
		byte[] arrayOfByte = B;
		int j = B.length;
		for (int i = 0; i < j; i++)
		{
			byte b = arrayOfByte[i];
			tmp = tmp + toHex(b);
		}
		return tmp;
	}
	
	private static byte[] toBytes(String Hex)
	{
		byte[] B = new byte[Hex.length() / 2];
		for (int i = 0; i + 1 < Hex.length(); i += 2)
		{
			String hexStr = Hex.substring(i, i + 2);
			B[(i / 2)] = toByte(hexStr);
		}
		
		return B;
	}
	
	private static String toHex(byte B)
	{
		int N = B + 128;
		return "" + (char) (65 + N / 26) + (char) (65 + N % 26);
	}
	
	private static byte toByte(String Hex)
	{
		int N = (Hex.charAt(0) - 'A') * 26 + (Hex.charAt(1) - 'A');
		return (byte) (N - 128);
	}
	
	
	/** 判斷資料是否為加密的資料 */
	public static boolean isEncrypt(String data)
	{
		return data.startsWith("DATA$");
	}
	
}