關於Android側使用AES進行加解密時的key和iv使用的方法

       AESCBC加密模式,默認iv是16個0(這個稱爲初始化向量),由於是分組加密,所以下一組的iv,就用前一組的加密的密文來充當,我們可以指定IV來進行加解密,加大破解難度。CFB、OFB模式類似,只不過更復雜。

        廢話不多說,直接上代碼:

        

       

package com.irisking.scanner.util;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import android.os.Environment;

public class AesUtil {
	private static int BUFFER_SIZE = 8192;
	/**
	 * 從指定文件獲取數據解密後存儲到另外一個文件
	 * 
	 * @param filePath  需解鎖文件路徑
	 * @param destFilePath  存儲文件路徑
	 */
	public static void decrypt(String filePath, String destFilePath) {
		MoreAES aes = MoreAES.getInstances();
		String keyPath = Environment.getExternalStorageDirectory().getAbsoluteFile() + "/key.dat";
		byte[] byteArrays = getBytesFromDat(keyPath);
		
		String ivPath = Environment.getExternalStorageDirectory().getAbsoluteFile() + "/iv.dat";
		byte[] ivArray = getBytesFromDat(ivPath);

		aes.decrypt(filePath, destFilePath, byteArrays,ivArray);
	}
	/**
	 * 獲取密鑰的byte數組
	 * @param keyPath
	 * @return
	 */
	private static byte[] getBytesFromDat(String keyPath) {
		FileInputStream fis = null;
		ByteArrayOutputStream baos = null;
		byte[] byteArrays = null;
		try {
			fis = new FileInputStream(keyPath);
			byte[] b = new byte[BUFFER_SIZE];
			int len;
			baos = new ByteArrayOutputStream();
			while ((len = fis.read(b)) != -1) {
				baos.write(b, 0, len);
			}
			byteArrays = baos.toByteArray();

		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {}
			}

			if (baos != null) {
				try {
					baos.flush();
				} catch (IOException e) {}

				try {
					baos.close();
				} catch (IOException e) {}

			}
		}
		return byteArrays;
	}
}

package com.irisking.scanner.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.security.InvalidAlgorithmParameterException;
import java.security.Key;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;

import javax.crypto.CipherInputStream;

import javax.crypto.CipherOutputStream;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import android.os.Environment;

public class MoreAES {

	private static String TYPE = "AES";

	private static int BUFFER_SIZE = 8192;
	
	private static MoreAES moreAes;
	
	private MoreAES(){}
	
	public synchronized static MoreAES getInstances(){
		if(moreAes == null){
			moreAes = new MoreAES();
		}
		return moreAes;
	}

	private static Cipher getCipher(int mode, byte[] key,byte[] iv) {
		// mode =Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
		Cipher mCipher;
		
		try {
			mCipher = Cipher.getInstance(TYPE + "/CBC/PKCS5Padding");
			
			Key keySpec = new SecretKeySpec(key, "AES");
			IvParameterSpec ivSpec = new IvParameterSpec(iv);
			
			mCipher.init(mode, keySpec, ivSpec);
			
			return mCipher;
		}catch (InvalidKeyException e) {
			e.printStackTrace();
		}catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 
	 * 解密文件
	 * @param srcFile
	 * @param destFile
	 * @param privateKey
	 */

	public void decrypt(String srcFile, String destFile, byte[] privateKey,byte[] privateIv) {

		byte[] readBuffer = new byte[BUFFER_SIZE];

		Cipher deCipher = getCipher(Cipher.DECRYPT_MODE, privateKey,privateIv);

		if (deCipher == null)
			return; // init failed.

		CipherInputStream fis = null;

		BufferedOutputStream fos = null;

		int size;

		try {

			fis = new CipherInputStream(new BufferedInputStream(new FileInputStream(srcFile)), deCipher);

			fos = new BufferedOutputStream(new FileOutputStream(mkdirFiles(destFile)));

			while ((size = fis.read(readBuffer, 0, BUFFER_SIZE)) >= 0) {

				fos.write(readBuffer, 0, size);

			}

			fos.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {}
			}

			if (fos != null) {
				try {
					fos.flush();
				} catch (IOException e) {}

				try {
					fos.close();
				} catch (IOException e) {}

			}
		}
	}

	/**
	 * 加密文件
	 * @param srcFile
	 * @param destFile
	 * @param privateKey
	 */

	public void crypt(String srcFile, String destFile, byte[] privateKey,byte[] privateIv) {

		byte[] readBuffer = new byte[BUFFER_SIZE];

		Cipher enCipher = getCipher(Cipher.ENCRYPT_MODE, privateKey,privateIv);

		if (enCipher == null)
			return; // init failed.

		CipherOutputStream fos = null;

		BufferedInputStream fis = null;

		int size;

		try {

			fos = new CipherOutputStream(new BufferedOutputStream(new FileOutputStream(destFile)), enCipher);

			fis = new BufferedInputStream(new FileInputStream(mkdirFiles(srcFile)));

			while ((size = fis.read(readBuffer, 0, BUFFER_SIZE)) >= 0) {

				fos.write(readBuffer, 0, size);
			}

			fos.flush();

		} catch (FileNotFoundException e) {

			e.printStackTrace();

		} catch (IOException e) {

			e.printStackTrace();

		} finally {

			if (fis != null) {

				try {
					fis.close();
				} catch (IOException e) {
				}

			}

			if (fos != null) {

				try {
					fos.flush();
				} catch (IOException e) {
				}

				try {
					fos.close();
				} catch (IOException e) {
				}

			}

		}

	}

	private static File mkdirFiles(String filePath) throws IOException {

		File file = new File(filePath);

		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}

		file.createNewFile();

		return file;
	}

}

     

個人聯繫方式:[email protected]



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章