android使用AES加密和解密文件

前言

最近公司需要对本公司的一些下载文件进行加密解密需求,也就尝试去实现下,其实需要借助第三方的jar包:bcprov-jdk15on-155.jar,下载这个可以到网上搜或者下载本人的demo即可,注意:需要加密和解密的key是一致的才可以解密,不然就会解密失败。不多说,直接上代码。

效果图



代码:

实现加密解密逻辑代码
[java]  view plain  copy
  1. package com.vsoontech.p2p.sample;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.OutputStream;  
  6. import java.security.InvalidKeyException;  
  7. import java.security.Key;  
  8. import java.security.NoSuchAlgorithmException;  
  9. import java.security.SecureRandom;  
  10.   
  11. import javax.crypto.BadPaddingException;  
  12. import javax.crypto.Cipher;  
  13. import javax.crypto.IllegalBlockSizeException;  
  14. import javax.crypto.KeyGenerator;  
  15. import javax.crypto.NoSuchPaddingException;  
  16. import javax.crypto.ShortBufferException;  
  17.   
  18. /** 
  19.  * @author zhou 
  20.  * @since 2016/9/26 
  21.  */  
  22.   
  23. public enum AES {  
  24.     INSTANCE;  
  25.     private Key key;  
  26.   
  27.     /** 
  28.      * 生成AES对称秘钥 
  29.      */  
  30.     public String generateKey() throws NoSuchAlgorithmException {  
  31.         KeyGenerator keygen = KeyGenerator.getInstance("AES");  
  32.         SecureRandom random = new SecureRandom();  
  33.         keygen.init(random);  
  34.         this.key = keygen.generateKey();  
  35.         return "Algorithm Format Encoded:" + key.getAlgorithm() + " - " + key.getFormat() + " - " + new String(key.getEncoded());  
  36.     }  
  37.   
  38.     /** 
  39.      * 加密 
  40.      */  
  41.     public void encrypt(InputStream in) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
  42.         this.crypt(in, null, Cipher.ENCRYPT_MODE);  
  43.     }  
  44.   
  45.     /** 
  46.      * 解密 
  47.      */  
  48.     public String decrypt(InputStream in) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
  49.         return this.crypt(in, Cipher.DECRYPT_MODE);  
  50.     }  
  51.   
  52.     /** 
  53.      * 加密 
  54.      */  
  55.     public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
  56.         this.crypt(in, out, Cipher.ENCRYPT_MODE);  
  57.     }  
  58.   
  59.     /** 
  60.      * 解密 
  61.      */  
  62.     public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
  63.         this.crypt(in, out, Cipher.DECRYPT_MODE);  
  64.     }  
  65.   
  66.     /** 
  67.      * 实际的加密解密过程 
  68.      */  
  69.     public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {  
  70.         Cipher cipher = Cipher.getInstance("AES");  
  71.         cipher.init(mode, this.key);  
  72.   
  73.         int blockSize = cipher.getBlockSize();  
  74.         int outputSize = cipher.getOutputSize(blockSize);  
  75.         byte[] inBytes = new byte[blockSize];  
  76.         byte[] outBytes = new byte[outputSize];  
  77.   
  78.         int inLength = 0;  
  79.         boolean more = true;  
  80.         while (more) {  
  81.             inLength = in.read(inBytes);  
  82.             if (inLength == blockSize) {   //只要输入数据块具有全长度(长度可被8整除),调用update方法  
  83.                 int outLength = cipher.update(inBytes, 0, blockSize, outBytes);  
  84.                 if (out != null) out.write(outBytes, 0, outLength);  
  85.             } else {  
  86.                 more = false;  
  87.             }  
  88.         }  
  89.         if (inLength > 0)   //不具有全长度,调用doFinal方法  
  90.             outBytes = cipher.doFinal(inBytes, 0, inLength);  
  91.         else  
  92.             outBytes = cipher.doFinal();  
  93.         if (out != null) {  
  94.             out.write(outBytes);  
  95.             out.flush();  
  96.         }  
  97.     }  
  98.   
  99.     /** 
  100.      * 实际的加密解密过程 
  101.      */  
  102.     public String crypt(InputStream in, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {  
  103.         Cipher cipher = Cipher.getInstance("AES");  
  104.         cipher.init(mode, this.key);  
  105.   
  106.         int blockSize = cipher.getBlockSize();  
  107.         int outputSize = cipher.getOutputSize(blockSize);  
  108.         byte[] inBytes = new byte[blockSize];  
  109.         byte[] outBytes = new byte[outputSize];  
  110.   
  111.         int inLength = 0;  
  112.         boolean more = true;  
  113.         StringBuilder sb = new StringBuilder();  
  114.         while (more) {  
  115.             inLength = in.read(inBytes);  
  116.             if (inLength == blockSize) {   //只要输入数据块具有全长度(长度可被8整除),调用update方法  
  117.                 int outLength = cipher.update(inBytes, 0, blockSize, outBytes);  
  118.             } else {  
  119.                 more = false;  
  120.             }  
  121.         }  
  122.         if (inLength > 0)   //不具有全长度,调用doFinal方法  
  123.             outBytes = cipher.doFinal(inBytes, 0, inLength);  
  124.         else  
  125.             outBytes = cipher.doFinal();  
  126.         sb.append(new String(outBytes));  
  127.         return sb.toString();  
  128.     }  
  129.   
  130.   
  131.     public void setKey(Key key) {  
  132.         this.key = key;  
  133.     }  
  134.   
  135.     public Key getKey() {  
  136.         return key;  
  137.     }  
  138. }  

生成秘钥代码
[java]  view plain  copy
  1. package com.vsoontech.p2p.sample;  
  2.   
  3. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  4.   
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.FileOutputStream;  
  8. import java.security.Key;  
  9. import java.security.NoSuchAlgorithmException;  
  10.   
  11. import javax.crypto.Cipher;  
  12. import javax.crypto.KeyGenerator;  
  13. import javax.crypto.SecretKey;  
  14. import javax.crypto.spec.IvParameterSpec;  
  15. import javax.crypto.spec.SecretKeySpec;  
  16.   
  17. /** 
  18.  * @author zhou 
  19.  * @since 2016/9/26 
  20.  */  
  21.   
  22. public class AESKeyModel {  
  23.     public static final String KEY_ALGORITHM = "AES";  
  24.     private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";  
  25.     private String srcFile = "", destionFile = "";  
  26.   
  27.     /** 
  28.      * 初始化密钥 
  29.      * 
  30.      * @return byte[] 密钥 
  31.      * @throws Exception 
  32.      */  
  33.     public byte[] initSecretKey() {  
  34.         //返回生成指定算法的秘密密钥的 KeyGenerator 对象  
  35.         KeyGenerator kg = null;  
  36.         try {  
  37.             kg = KeyGenerator.getInstance(KEY_ALGORITHM);  
  38.         } catch (NoSuchAlgorithmException e) {  
  39.             e.printStackTrace();  
  40.             return new byte[0];  
  41.         }  
  42.         //初始化此密钥生成器,使其具有确定的密钥大小  
  43.         //AES 要求密钥长度为 128  
  44.         kg.init(128);  
  45.         //生成一个密钥  
  46.         SecretKey secretKey = kg.generateKey();  
  47.         return secretKey.getEncoded();  
  48.     }  
  49.   
  50.     public void setDestionFile(String destionFile) {  
  51.         this.destionFile = destionFile;  
  52.     }  
  53.   
  54.     public void setSrcFile(String srcFile) {  
  55.         this.srcFile = srcFile;  
  56.     }  
  57.   
  58.     /** 
  59.      * 转换密钥 
  60.      * 
  61.      * @param key 二进制密钥 
  62.      * @return 密钥 
  63.      */  
  64.     private static Key toKey(byte[] key) {  
  65.         //生成密钥  
  66.         return new SecretKeySpec(key, KEY_ALGORITHM);  
  67.     }  
  68.   
  69.     /** 
  70.      * 加密 
  71.      * 
  72.      * @param data 待加密数据 
  73.      * @param key  密钥 
  74.      * @return byte[]   加密数据 
  75.      * @throws Exception 
  76.      */  
  77.     public static byte[] encrypt(byte[] data, Key key) throws Exception {  
  78.         return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);  
  79.     }  
  80.   
  81.     /** 
  82.      * 加密 
  83.      * 
  84.      * @param data 待加密数据 
  85.      * @param key  二进制密钥 
  86.      * @return byte[]   加密数据 
  87.      * @throws Exception 
  88.      */  
  89.     public static byte[] encrypt(byte[] data, byte[] key) throws Exception {  
  90.         return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);  
  91.     }  
  92.   
  93.   
  94.     /** 
  95.      * 加密 
  96.      * 
  97.      * @param data            待加密数据 
  98.      * @param key             二进制密钥 
  99.      * @param cipherAlgorithm 加密算法/工作模式/填充方式 
  100.      * @return byte[]   加密数据 
  101.      * @throws Exception 
  102.      */  
  103.     public static byte[] encrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {  
  104.         //还原密钥  
  105.         Key k = toKey(key);  
  106.         return encrypt(data, k, cipherAlgorithm);  
  107.     }  
  108.   
  109.     /** 
  110.      * 加密 
  111.      * 
  112.      * @param data            待加密数据 
  113.      * @param key             密钥 
  114.      * @param cipherAlgorithm 加密算法/工作模式/填充方式 
  115.      * @return byte[]   加密数据 
  116.      * @throws Exception 
  117.      */  
  118.     public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {  
  119.         //实例化  
  120.         Cipher cipher = Cipher.getInstance(cipherAlgorithm);  
  121.         //使用密钥初始化,设置为加密模式  
  122.         cipher.init(Cipher.ENCRYPT_MODE, key);  
  123.         //执行操作  
  124.         return cipher.doFinal(data);  
  125.     }  
  126.   
  127.     /** 
  128.      * 解密 
  129.      * 
  130.      * @param data 待解密数据 
  131.      * @param key  二进制密钥 
  132.      * @return byte[]   解密数据 
  133.      * @throws Exception 
  134.      */  
  135.     public static byte[] decrypt(byte[] data, byte[] key) throws Exception {  
  136.         return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);  
  137.     }  
  138.   
  139.     /** 
  140.      * 解密 
  141.      * 
  142.      * @param data 待解密数据 
  143.      * @param key  密钥 
  144.      * @return byte[]   解密数据 
  145.      * @throws Exception 
  146.      */  
  147.     public static byte[] decrypt(byte[] data, Key key) throws Exception {  
  148.         return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);  
  149.     }  
  150.   
  151.     /** 
  152.      * 解密 
  153.      * 
  154.      * @param data            待解密数据 
  155.      * @param key             二进制密钥 
  156.      * @param cipherAlgorithm 加密算法/工作模式/填充方式 
  157.      * @return byte[]   解密数据 
  158.      * @throws Exception 
  159.      */  
  160.     public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {  
  161.         //还原密钥  
  162.         Key k = toKey(key);  
  163.         return decrypt(data, k, cipherAlgorithm);  
  164.     }  
  165.   
  166.     /** 
  167.      * 解密 
  168.      * 
  169.      * @param data            待解密数据 
  170.      * @param key             密钥 
  171.      * @param cipherAlgorithm 加密算法/工作模式/填充方式 
  172.      * @return byte[]   解密数据 
  173.      * @throws Exception 
  174.      */  
  175.     public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {  
  176.         //实例化  
  177.         Cipher cipher = Cipher.getInstance(cipherAlgorithm);  
  178.         //使用密钥初始化,设置为解密模式  
  179.         cipher.init(Cipher.DECRYPT_MODE, key);  
  180.         //执行操作  
  181.         return cipher.doFinal(data);  
  182.     }  
  183.   
  184.     public void encryptionFile(Key sessionKey) throws Exception {  
  185.         int len = 0;  
  186.         byte[] buffer = new byte[1024];  
  187.         byte[] cipherbuffer = null;  
  188.   
  189.         // 使用会话密钥对文件加密。  
  190.         Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM, new BouncyCastleProvider());  
  191.         IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());  
  192.         cipher.init(Cipher.ENCRYPT_MODE, sessionKey, iv);  
  193.   
  194.         FileInputStream fis = new FileInputStream(new File(srcFile));  
  195.         FileOutputStream fos = new FileOutputStream(new File(destionFile));  
  196.   
  197.         // 读取原文,加密并写密文到输出文件。  
  198.         while ((len = fis.read(buffer)) != -1) {  
  199.             cipherbuffer = cipher.update(buffer, 0, len);  
  200.             fos.write(cipherbuffer);  
  201.             fos.flush();  
  202.         }  
  203.         cipherbuffer = cipher.doFinal();  
  204.         fos.write(cipherbuffer);  
  205.         fos.flush();  
  206.   
  207.         if (fis != null)  
  208.             fis.close();  
  209.         if (fos != null)  
  210.             fos.close();  
  211.     }  
  212.   
  213.     public void descryptionFile(Key sessionKey) throws Exception {  
  214.         int len = 0;  
  215.         byte[] buffer = new byte[5 * 1024];  
  216.         byte[] plainbuffer = null;  
  217.   
  218.         Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM, new BouncyCastleProvider());  
  219.         IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());  
  220.         cipher.init(Cipher.DECRYPT_MODE, sessionKey, iv);  
  221.   
  222.         FileInputStream fis = new FileInputStream(new File(srcFile));  
  223.         FileOutputStream fos = new FileOutputStream(new File(destionFile));  
  224.   
  225.         while ((len = fis.read(buffer)) != -1) {  
  226.             plainbuffer = cipher.update(buffer, 0, len);  
  227.             fos.write(plainbuffer);  
  228.             fos.flush();  
  229.         }  
  230.   
  231.         plainbuffer = cipher.doFinal();  
  232.         fos.write(plainbuffer);  
  233.         fos.flush();  
  234.   
  235.         if (fis != null)  
  236.             fis.close();  
  237.         if (fos != null)  
  238.             fos.close();  
  239.     }  
  240. }  

加密逻辑示例代码
[java]  view plain  copy
  1. /** 
  2.      * 加密 
  3.      * 
  4.      * @param path 
  5.      * @param destionFile 
  6.      */  
  7.     private void aes(String path, String destionFile) {  
  8.         try {  
  9.             Log.d(TAG, "aes Key: " + AES.INSTANCE.generateKey());  
  10.             FileInputStream fis = new FileInputStream(new File(path));  
  11.             FileOutputStream fos = new FileOutputStream(new File(destionFile));  
  12.             AES.INSTANCE.encrypt(fis, fos);  
  13.         } catch (Exception e) {  
  14.             Log.d(TAG, "Exception: " + e.toString());  
  15.             e.printStackTrace();  
  16.         }  
  17.   
  18.     }  

解密逻辑示例代码:
[java]  view plain  copy
  1. /** 
  2.      * AES解密文件 
  3.      * 
  4.      * @param path 需要解密的文件目录 
  5.      */  
  6.     private void aesJieMi(String path) {  
  7.         File f = new File(path);  
  8.         if (!f.exists() || f.isDirectory())  
  9.             Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show();  
  10.         else {  
  11.             String prefix = f.getName().substring(0, f.getName().indexOf('.'));  
  12.             String suffix = f.getName().substring(f.getName().indexOf('.'));  
  13.             String outjiemiFile = Environment.getExternalStorageDirectory() + File.separator + prefix + "AES_jieMi" + suffix;  
  14.   
  15.             AESKeyModel model_aes = new AESKeyModel();  
  16.             model_aes.setSrcFile(path);  
  17.             model_aes.setDestionFile(outjiemiFile);  
  18.   
  19.             try {  
  20. //                model_aes.descryptionFile(key_AES);  
  21.                 model_aes.descryptionFile(key_aes);  
  22.                 // TODO: 加密后的文件  
  23.                 RandomAccessFile raf = new RandomAccessFile(path, "rw");  
  24.                 Log.d(TAG, "解密后 file length: " + raf.length());  
  25.                 Log.d(TAG, "解密后 file content: " + raf.readLine());  
  26.             } catch (Exception e) {  
  27.                 e.printStackTrace();  
  28.             }  
  29.         }  
  30.     }  

总结:

注意秘钥需要一致。

代码链接地址: 点击打开链接

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这里是一个简单的示例,展示了如何在 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` 是加密或解密后的文件路径。 请注意,此示例中的加密和解密操作是阻塞的,并且使用了相对较小的缓冲区。对于大文件和需要异步处理的情况,您需要进行适当的优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值