android使用AES加密和解密文件实例代码
时间:2019-03-30
本文章向大家介绍android使用AES加密和解密文件实例代码,主要包括android使用AES加密和解密文件实例代码使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
最近公司需要对本公司的一些下载文件进行加密解密需求,也就尝试去实现下,其实需要借助第三方的jar包:bcprov-jdk15on-155.jar,下载这个可以到网上搜或者下载本人的demo即可,注意:需要加密和解密的key是一致的才可以解密,不然就会解密失败。不多说,直接上代码。
效果图
代码:
实现加密解密逻辑代码
package com.vsoontech.p2p.sample; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; /** * @author zhou * @since 2016/9/26 */ public enum AES { INSTANCE; private Key key; /** * 生成AES对称秘钥 */ public String generateKey() throws NoSuchAlgorithmException { KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecureRandom random = new SecureRandom(); keygen.init(random); this.key = keygen.generateKey(); return "Algorithm Format Encoded:" + key.getAlgorithm() + " - " + key.getFormat() + " - " + new String(key.getEncoded()); } /** * 加密 */ public void encrypt(InputStream in) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException { this.crypt(in, null, Cipher.ENCRYPT_MODE); } /** * 解密 */ public String decrypt(InputStream in) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException { return this.crypt(in, Cipher.DECRYPT_MODE); } /** * 加密 */ public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException { this.crypt(in, out, Cipher.ENCRYPT_MODE); } /** * 解密 */ public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException { this.crypt(in, out, Cipher.DECRYPT_MODE); } /** * 实际的加密解密过程 */ public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { Cipher cipher = Cipher.getInstance("AES"); cipher.init(mode, this.key); int blockSize = cipher.getBlockSize(); int outputSize = cipher.getOutputSize(blockSize); byte[] inBytes = new byte[blockSize]; byte[] outBytes = new byte[outputSize]; int inLength = 0; boolean more = true; while (more) { inLength = in.read(inBytes); if (inLength == blockSize) { //只要输入数据块具有全长度(长度可被8整除),调用update方法 int outLength = cipher.update(inBytes, 0, blockSize, outBytes); if (out != null) out.write(outBytes, 0, outLength); } else { more = false; } } if (inLength > 0) //不具有全长度,调用doFinal方法 outBytes = cipher.doFinal(inBytes, 0, inLength); else outBytes = cipher.doFinal(); if (out != null) { out.write(outBytes); out.flush(); } } /** * 实际的加密解密过程 */ public String crypt(InputStream in, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { Cipher cipher = Cipher.getInstance("AES"); cipher.init(mode, this.key); int blockSize = cipher.getBlockSize(); int outputSize = cipher.getOutputSize(blockSize); byte[] inBytes = new byte[blockSize]; byte[] outBytes = new byte[outputSize]; int inLength = 0; boolean more = true; StringBuilder sb = new StringBuilder(); while (more) { inLength = in.read(inBytes); if (inLength == blockSize) { //只要输入数据块具有全长度(长度可被8整除),调用update方法 int outLength = cipher.update(inBytes, 0, blockSize, outBytes); } else { more = false; } } if (inLength > 0) //不具有全长度,调用doFinal方法 outBytes = cipher.doFinal(inBytes, 0, inLength); else outBytes = cipher.doFinal(); sb.append(new String(outBytes)); return sb.toString(); } public void setKey(Key key) { this.key = key; } public Key getKey() { return key; } }
生成秘钥代码
package com.vsoontech.p2p.sample; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * @author zhou * @since 2016/9/26 */ public class AESKeyModel { public static final String KEY_ALGORITHM = "AES"; private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; private String srcFile = "", destionFile = ""; /** * 初始化密钥 * * @return byte[] 密钥 * @throws Exception */ public byte[] initSecretKey() { //返回生成指定算法的秘密密钥的 KeyGenerator 对象 KeyGenerator kg = null; try { kg = KeyGenerator.getInstance(KEY_ALGORITHM); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return new byte[0]; } //初始化此密钥生成器,使其具有确定的密钥大小 //AES 要求密钥长度为 128 kg.init(128); //生成一个密钥 SecretKey secretKey = kg.generateKey(); return secretKey.getEncoded(); } public void setDestionFile(String destionFile) { this.destionFile = destionFile; } public void setSrcFile(String srcFile) { this.srcFile = srcFile; } /** * 转换密钥 * * @param key 二进制密钥 * @return 密钥 */ private static Key toKey(byte[] key) { //生成密钥 return new SecretKeySpec(key, KEY_ALGORITHM); } /** * 加密 * * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data, Key key) throws Exception { return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM); } /** * 加密 * * @param data 待加密数据 * @param key 二进制密钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data, byte[] key) throws Exception { return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM); } /** * 加密 * * @param data 待加密数据 * @param key 二进制密钥 * @param cipherAlgorithm 加密算法/工作模式/填充方式 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception { //还原密钥 Key k = toKey(key); return encrypt(data, k, cipherAlgorithm); } /** * 加密 * * @param data 待加密数据 * @param key 密钥 * @param cipherAlgorithm 加密算法/工作模式/填充方式 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception { //实例化 Cipher cipher = Cipher.getInstance(cipherAlgorithm); //使用密钥初始化,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, key); //执行操作 return cipher.doFinal(data); } /** * 解密 * * @param data 待解密数据 * @param key 二进制密钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data, byte[] key) throws Exception { return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM); } /** * 解密 * * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data, Key key) throws Exception { return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM); } /** * 解密 * * @param data 待解密数据 * @param key 二进制密钥 * @param cipherAlgorithm 加密算法/工作模式/填充方式 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception { //还原密钥 Key k = toKey(key); return decrypt(data, k, cipherAlgorithm); } /** * 解密 * * @param data 待解密数据 * @param key 密钥 * @param cipherAlgorithm 加密算法/工作模式/填充方式 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception { //实例化 Cipher cipher = Cipher.getInstance(cipherAlgorithm); //使用密钥初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, key); //执行操作 return cipher.doFinal(data); } public void encryptionFile(Key sessionKey) throws Exception { int len = 0; byte[] buffer = new byte[1024]; byte[] cipherbuffer = null; // 使用会话密钥对文件加密。 Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM, new BouncyCastleProvider()); IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes()); cipher.init(Cipher.ENCRYPT_MODE, sessionKey, iv); FileInputStream fis = new FileInputStream(new File(srcFile)); FileOutputStream fos = new FileOutputStream(new File(destionFile)); // 读取原文,加密并写密文到输出文件。 while ((len = fis.read(buffer)) != -1) { cipherbuffer = cipher.update(buffer, 0, len); fos.write(cipherbuffer); fos.flush(); } cipherbuffer = cipher.doFinal(); fos.write(cipherbuffer); fos.flush(); if (fis != null) fis.close(); if (fos != null) fos.close(); } public void descryptionFile(Key sessionKey) throws Exception { int len = 0; byte[] buffer = new byte[5 * 1024]; byte[] plainbuffer = null; Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM, new BouncyCastleProvider()); IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes()); cipher.init(Cipher.DECRYPT_MODE, sessionKey, iv); FileInputStream fis = new FileInputStream(new File(srcFile)); FileOutputStream fos = new FileOutputStream(new File(destionFile)); while ((len = fis.read(buffer)) != -1) { plainbuffer = cipher.update(buffer, 0, len); fos.write(plainbuffer); fos.flush(); } plainbuffer = cipher.doFinal(); fos.write(plainbuffer); fos.flush(); if (fis != null) fis.close(); if (fos != null) fos.close(); } }
加密逻辑示例代码
/** * 加密 * * @param path * @param destionFile */ private void aes(String path, String destionFile) { try { Log.d(TAG, "aes Key: " + AES.INSTANCE.generateKey()); FileInputStream fis = new FileInputStream(new File(path)); FileOutputStream fos = new FileOutputStream(new File(destionFile)); AES.INSTANCE.encrypt(fis, fos); } catch (Exception e) { Log.d(TAG, "Exception: " + e.toString()); e.printStackTrace(); } }
解密逻辑示例代码:
/** * AES解密文件 * * @param path 需要解密的文件目录 */ private void aesJieMi(String path) { File f = new File(path); if (!f.exists() || f.isDirectory()) Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show(); else { String prefix = f.getName().substring(0, f.getName().indexOf('.')); String suffix = f.getName().substring(f.getName().indexOf('.')); String outjiemiFile = Environment.getExternalStorageDirectory() + File.separator + prefix + "AES_jieMi" + suffix; AESKeyModel model_aes = new AESKeyModel(); model_aes.setSrcFile(path); model_aes.setDestionFile(outjiemiFile); try { // model_aes.descryptionFile(key_AES); model_aes.descryptionFile(key_aes); // TODO: 加密后的文件 RandomAccessFile raf = new RandomAccessFile(path, "rw"); Log.d(TAG, "解密后 file length: " + raf.length()); Log.d(TAG, "解密后 file content: " + raf.readLine()); } catch (Exception e) { e.printStackTrace(); } } }
总结:
注意秘钥需要一致。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 第18天:NLP实战(二)——用DNN实现手势识别
- 「0821更新」Flutter入门系列教程汇总
- (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
- 第19天:NLP实战(三)——用CNN实现微博谣言检测
- (Demo分享)利用原生JavaScript-ScrollLeft-实现做轮播广告通知
- Flutter问题:Column里面嵌套两个SingleChildScrollView无法滚动
- 搞不懂JS中赋值·浅拷贝·深拷贝的请看这里
- 第20天:NLP实战(四)——用GRU模型实现电影评论情感分析
- Flutter SingleChildScrollView 滚动控件
- Flutter Stack、Positioned 层叠布局
- Flutter Row、Column 线性布局
- 第21天:NLP实战(五)——词向量Skip-gram实践
- ES10(2019)有哪些更新和新特性?
- Flutter Icon IconFont(图标控件)
- Flutter TextField(输入控件)