package com.example.aspectjandroidtest; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import org.apache.http.util.EncodingUtils; import com.facebook.crypto.Crypto; import com.facebook.crypto.Entity; import com.facebook.crypto.keychain.SharedPrefsBackedKeyChain; import com.facebook.crypto.util.SystemNativeCryptoLibrary; public aspect FileAspectJ { private boolean isEncryption = true; //使用秘钥链和原生库的默认实现,来创建一个新的加密对象 Crypto crypto = new Crypto( new SharedPrefsBackedKeyChain(MainActivity.context), new SystemNativeCryptoLibrary()); //创建应用文件的切点集合 pointcut openFileOutput(String filename,int mode) : !within(FileAspectJ) && args(filename,mode) && call(* openFileOutput(..)); after (String filename,int mode) returning : openFileOutput(filename, mode){ //System.out.println("fx Aspectj openFile is start"); byte[] buffer; try { System.out.println("fx Aspectj openFileName"+filename); buffer = filename.getBytes("UTF8"); FileOutputStream fileOutputStream = null; try { //记录本应用加密过的文件 fileOutputStream = MainActivity.context.openFileOutput("fileList", MainActivity.context.MODE_APPEND); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { fileOutputStream.write(buffer); fileOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //读取应用文件的切点集合 pointcut openFileInput(String filename) : !within(FileAspectJ) && args(filename) && call(* openFileInput(..)); before(String filename) : openFileInput(filename){ String result = ""; try { FileInputStream fileInputStream = MainActivity.context.openFileInput("fileList"); int bufferSize = 0; try { bufferSize = fileInputStream.available(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 取得输入流的字节长度 byte buffer[] = new byte[bufferSize]; try { fileInputStream.read(buffer); fileInputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } result = EncodingUtils.getString(buffer, "UTF-8"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } //判断文件是否加密过 if(result.indexOf(filename) == -1){ isEncryption = false;//未加密 System.out.println("fx 文件未加密"); }else{ isEncryption = true;//已加密 System.out.println("fx 文件已加密"); } } //截获到File的new操作 pointcut filePointcut(String pathname ) : !within(FileAspectJ) && args(pathname) && call(java.io.File.new(..)); before(String pathname ) : filePointcut(pathname) { System.out.println("fx pathname is " + pathname); } //写文件切点的集合 pointcut writePointcut(FileOutputStream fileStream, byte[] buffer) : !within(FileAspectJ) && target(fileStream)&& args(buffer) && call(* write(..)); void around(FileOutputStream fileStream, byte[] buffer) : writePointcut(fileStream, buffer) { System.out.println("fx Aspectj write is start"); //检查加密功能是否可用 //如果Android没有正确载入库,则此步骤可能失败 if (!crypto.isAvailable()) { System.out.println("return error"); return; } OutputStream fbFileStream = new BufferedOutputStream(fileStream); try { //创建输出流,当数据写入流的时候进行加密,并将加密后的数据输出到文件 OutputStream outputStream = crypto.getCipherOutputStream( fbFileStream, new Entity("test")); outputStream.write(buffer); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } } //读文件切点集合 pointcut readPointcut(FileInputStream fileStream, byte[] buffer) : !within(FileAspectJ) && target(fileStream)&& args(buffer) && call(* read(..)); int around(FileInputStream fileStream, byte[] buffer) : readPointcut(fileStream, buffer) { System.out.println("fx Aspectj read is start"); int bufferSize = 0; if(isEncryption==false){ return 0; } try { //文件流解密操作 InputStream inputStream = crypto.getCipherInputStream(fileStream, new Entity("test")); bufferSize = inputStream.available(); // 取得输入流的字节长度 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] data = new byte[1024]; int len; if (inputStream != null) { try { while ((len = inputStream.read(data)) != -1) { outputStream.write(data, 0, len); } data = outputStream.toByteArray(); } catch (IOException e) { } } for(int i = 0;i<data.length;i++) { buffer[i] = data[i]; } inputStream.close(); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } return bufferSize; } }