【Android】【加密】Android AES 文件加密

此4种文件加密方式,均验证(7501)

代码一

public boolean AESCipher(int cipherMode, String sourceFilePath, String targetFilePath, String seed) {
		
		if (cipherMode != Cipher.ENCRYPT_MODE  && cipherMode != Cipher.DECRYPT_MODE) {  
			return false;  
		}
		
		boolean result = false;  
		FileChannel sourceFC = null;  
		FileChannel targetFC = null;

		try{
			File sourceFile = new File(sourceFilePath);  
			File targetFile = new File(targetFilePath); 
			sourceFC = new RandomAccessFile(sourceFile, "r").getChannel();  
			targetFC = new RandomAccessFile(targetFile, "rw").getChannel(); 

			byte[] rawkey = getRawKey(seed.getBytes());  
			SecretKeySpec secretKey = new SecretKeySpec(rawkey, "AES");  
			Cipher mCipher = Cipher.getInstance("AES/CFB/NoPadding");
			mCipher.init(cipherMode, secretKey, new IvParameterSpec(new byte[mCipher.getBlockSize()]));  

			ByteBuffer byteData = ByteBuffer.allocate(1024); 

			while (sourceFC.read(byteData) != -1) {  
				// 通过通道读写交叉进行。  
				// 将缓冲区准备为数据传出状态  
				byteData.flip();  

				byte[] byteList = new byte[byteData.remaining()];  
				byteData.get(byteList, 0, byteList.length);  
				//此处,若不使用数组加密解密会失败,因为当byteData达不到1024个时,加密方式不同对空白字节的处理也不相同,从而导致成功与失败。   
				byte[] bytes = mCipher.doFinal(byteList);  
				targetFC.write(ByteBuffer.wrap(bytes));  
				byteData.clear();  
			}  

			result = true;  

		}catch(Exception e){
			Log.e(TAG, e.getMessage(), e);
		}finally{
			try {  
                if (sourceFC != null) {  
                    sourceFC.close();  
                }  
                if (targetFC != null) {  
                    targetFC.close();  
                }  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage(), e);  
            }  
		}

		return result;
	}

	/** 
	 * 使用一个安全的随机数来产生一个密匙,密匙加密使用的 
	 *  
	 * @param seed 
	 * @return 
	 * @throws NoSuchAlgorithmException 
	 */  
	private byte[] getRawKey(byte[] seed) throws Exception {  
		// 获得一个随机数,传入的参数为默认方式。  
		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
		// 设置一个种子,一般是用户设定的密码  
		sr.setSeed(seed);  
		// 获得一个key生成器(AES加密模式)  
		KeyGenerator keyGen = KeyGenerator.getInstance("AES");  
		// 设置密匙长度128位  
		keyGen.init(128, sr);  
		// 获得密匙  
		SecretKey key = keyGen.generateKey();  
		// 返回密匙的byte数组供加解密使用  
		byte[] raw = key.getEncoded();  
		return raw;  
	}  

方式二

// AES/CBC/NoPadding				no
	// AES/CBC/PKCS5Padding		no
	// AES/CBC/ISO10126Padding	no
	
	// AES/CFB/NoPadding               无异常,但解密后的图片,打开后无内容
	// AES/CFB/PKCS5Padding         no
	// AES/CFB/ISO10126Padding	 no
	
	// AES/ECB/NoPadding               no
	// AES/ECB/PKCS5Padding         no
	// AES/ECB/ISO10126Padding    no, pad block corrupted when decrypt
	
	// AES/OFB/NoPadding               无异常,但解密后的图片,打开后无内容
	// AES/OFB/PKCS5Padding          no  
	// AES/OFB/ISO10126Padding     no
	
	// AES/PCBC/NoPadding              no
	// AES/PCBC/PKCS5Padding         no
	// AES/PCBC/ISO10126Padding    no 
	
	private static final String TRANSFORMATION = "AES";
	private static final String ALGORITHM = "AES";
	private static final int KEY_SIZE = 128;
	private static final int CACHE_SIZE = 1024;

	public static void encryptFile(String sourceFilePath, String destFilePath)  throws Exception{
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		destFile.createNewFile();

		InputStream is = null; 
		OutputStream os = null;
		CipherInputStream cis = null;

		is = new FileInputStream(sourceFile);
		os = new FileOutputStream(destFile);

		// key
		String seed = "abc";
		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
		sr.setSeed(seed.getBytes());
		
		KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);  
//		kgen.init(KEY_SIZE);
		kgen.init(KEY_SIZE, sr);
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();  
		SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);  

		//  Cipher
		Cipher cipher = Cipher.getInstance(TRANSFORMATION); 
		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
		cis = new CipherInputStream(is, cipher);

		byte[] cache = new byte[CACHE_SIZE];
		int nRead = 0;
		while ((nRead = cis.read(cache)) != -1) {
			os.write(cache, 0, nRead);
			os.flush();
		}
		
		os.close();
		cis.close();
		is.close();
	}

	public static void decryptFile(String sourceFilePath, String destFilePath)  throws Exception{
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		destFile.createNewFile();

		InputStream is = null; 
		OutputStream os = null;
		CipherOutputStream cos = null;

		is = new FileInputStream(sourceFile);
		os = new FileOutputStream(destFile);

		// key
		String seed = "abc";
		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
		sr.setSeed(seed.getBytes());
		
		KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);  
//		kgen.init(KEY_SIZE);
		kgen.init(KEY_SIZE, sr);
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();  
		SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);  

		Cipher cipher = Cipher.getInstance(TRANSFORMATION); 
		cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
		cos = new CipherOutputStream(os, cipher);

		byte[] cache = new byte[CACHE_SIZE];
		int nRead = 0;
		while ((nRead = is.read(cache)) != -1) {
			cos.write(cache, 0, nRead);
			cos.flush();
		}
		
		cos.close();
		os.close();
		is.close();
	}

方式三

private static final int CACHE_SIZE = 1024;
	
	public static void encryptFile(String sourceFilePath, String destFilePath)  throws Exception{
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		destFile.createNewFile();
		
		InputStream is = new FileInputStream(sourceFile); 
		OutputStream os = new FileOutputStream(destFile);
		
		int seed = 1;
		os.write(seed);
		
		byte[] cache = new byte[CACHE_SIZE];
		int nRead = 0;
		while ((nRead = is.read(cache)) != -1) {
			os.write(cache, 0, nRead);
			os.flush();
		}
		
		os.close();
		is.close();
	}
	
	public static void decryptFile(String sourceFilePath, String destFilePath)  throws Exception{
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		destFile.createNewFile();
		
		InputStream is = new FileInputStream(sourceFile); 
		OutputStream os = new FileOutputStream(destFile);

		int seed = is.read();
		Log.d(TAG, "seed: " + seed);
		
		byte[] cache = new byte[CACHE_SIZE];
		int nRead = 0;
		while ((nRead = is.read(cache)) != -1) {
			os.write(cache, 0, nRead);
			os.flush();
		}
		
		os.close();
		is.close();
	}

方式四

public static void encryptFile(String sourceFilePath)  throws Exception{

		RandomAccessFile file = new RandomAccessFile(sourceFilePath, "rw");

		file.seek(0);
		byte first = file.readByte();
		byte second = file.readByte();
		
		file.seek(0);
		file.writeByte(second);
		file.writeByte(first);

		file.close();
	}


注:部分代码源于网络,但已记不清源自哪里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个简单的示例,展示了如何在 Android 中使用 AES 加密解密文件: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.MessageDigest; import java.util.Arrays; public class AesUtil { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String SECRET_KEY = "my_secret_key"; private static final String IV = "my_initialization_vector"; public static void encrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } public static void decrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } private static SecretKeySpec generateKey(String key) throws Exception { byte[] keyBytes = key.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-256"); keyBytes = sha.digest(keyBytes); keyBytes = Arrays.copyOf(keyBytes, 16); return new SecretKeySpec(keyBytes, "AES"); } } ``` 在此示例中,我们使用 AES/CBC/PKCS5Padding 加密模式和 SHA-256 哈希算法生成密钥。我们将密钥和初始向量 IV 保存为常量,但您可以根据需要进行更改。 要使用此示例,请在您的代码中调用 `AesUtil.encrypt(inputFile, outputFile)` 或 `AesUtil.decrypt(inputFile, outputFile)` 方法,其中 `inputFile` 是要加密解密文件路径,而 `outputFile` 是加密解密后的文件路径。 请注意,此示例中的加密解密操作是阻塞的,并且使用了相对较小的缓冲区。对于大文件和需要异步处理的情况,您需要进行适当的优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值