标签:AES java String destFilePath sourceFilePath key new 加密算法 加密
文件流加密涉及到大文件加密过程,不能直接使用Cipher.doFinal(byte[] bytes)方法进行直接加密
超大文件会导致内存溢出。
解决方法:
可以使用 Cipher.update(byte[] bytes) 方法进行文件流部分加密数据, 当整个文件流数据都加密完后,使用 Cipher.doFinal()方法来生成填充内容,保证最后一段内容也是完整128位数据块
所以会使用CipherInputStream 或者 CipherOutputStream进行文件加解密
使用上面中了一个就可以了。或者也可以混着用
说下原理:
CipherInputStream
对输入流进行封装 CipherInputStream.read()读取字节流时调用的cipher.update()方法进行流部分加密, 当加密到最后一段时,会调用 doFinal() 方法。
CipherOutputStream
对输出流进行封装,当要写入固定字节数据时,先加密,再写出 CipherOutputStream.write() 中调用 cipher.update() 方法进行字节数组加密后写出 再CipherOutputStream.close()中调用cipher.doFinal()方法 填充最后一段内容
贴个示例代码
public static void aesEncryptFile(String sourceFilePath, String destFilePath, String key) throws Exception { aesFile(sourceFilePath, destFilePath, key, Cipher.ENCRYPT_MODE); } public static void aesDecryptFile(String sourceFilePath, String destFilePath, String key) throws Exception { aesFile(sourceFilePath, destFilePath, key, Cipher.DECRYPT_MODE); } public static void aesEncryptFileForInput(String sourceFilePath, String destFilePath, String key) throws Exception { aesFileForInput(sourceFilePath, destFilePath, key, Cipher.ENCRYPT_MODE); } public static void aesDecryptFileForInput(String sourceFilePath, String destFilePath, String key) throws Exception { aesFileForInput(sourceFilePath, destFilePath, key, Cipher.DECRYPT_MODE); } /** * 通过文件输入流加密文件并输出到指定路径 * CipherOutputStream进行加密数据 */ public static void aesFile(String sourceFilePath, String destFilePath, String key, int mode) throws Exception { File sourceFile = new File(sourceFilePath); File destFile = new File(destFilePath); if (sourceFile.exists() && sourceFile.isFile()) { throw new IllegalArgumentException("加密源文件不存在"); } if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); InputStream in = new FileInputStream(sourceFile); OutputStream out = new FileOutputStream(destFile); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES/ECB/PKCS5Padding"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(mode, secretKeySpec); // 对输出流包装 CipherOutputStream cout = new CipherOutputStream(out, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { cout.write(cache, 0, nRead); cout.flush(); } cout.close(); out.close(); in.close(); } /** * 通过文件输入流加密文件并输出到指定路径 * CipherInputStream进行加密数据 */ public static void aesFileForInput(String sourceFilePath, String destFilePath, String key, int mode) throws Exception { File sourceFile = new File(sourceFilePath); File destFile = new File(destFilePath); if (sourceFile.exists() && sourceFile.isFile()) { throw new IllegalArgumentException("加密源文件不存在"); } if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); InputStream in = new FileInputStream(sourceFile); OutputStream out = new FileOutputStream(destFile); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES/ECB/PKCS5Padding"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(mode, secretKeySpec); // 对输入流包装 CipherInputStream cin = new CipherInputStream(in, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = cin.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); cin.close(); in.close(); }
标签:AES,java,String,destFilePath,sourceFilePath,key,new,加密算法,加密 来源: https://www.cnblogs.com/gne-hwz/p/14736496.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。