Java AES文件加解密

jopen 7年前

之前写了DES加解密,AES几乎与之相同,不同的是底层key的位数而已,不过这些对于我们使用者都是透明的。

AESUtils.java

package demo.security;    import java.io.File;  import java.io.FileInputStream;  import java.io.FileOutputStream;  import java.io.InputStream;  import java.io.OutputStream;  import java.security.Key;  import java.security.SecureRandom;    import javax.crypto.Cipher;  import javax.crypto.CipherInputStream;  import javax.crypto.CipherOutputStream;  import javax.crypto.KeyGenerator;  import javax.crypto.SecretKey;  import javax.crypto.spec.SecretKeySpec;    /**   * <p>   * AES加密解密工具包   * </p>   *    * @author IceWee   * @date 2012-5-18   * @version 1.0   */  public class AESUtils {        private static final String ALGORITHM = "AES";      private static final int KEY_SIZE = 128;      private static final int CACHE_SIZE = 1024;            /**       * <p>       * 生成随机密钥       * </p>       *        * @return       * @throws Exception       */      public static String getSecretKey() throws Exception {          return getSecretKey(null);      }            /**       * <p>       * 生成密钥       * </p>       *        * @param seed 密钥种子       * @return       * @throws Exception       */      public static String getSecretKey(String seed) throws Exception {          KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);          SecureRandom secureRandom;          if (seed != null && !"".equals(seed)) {              secureRandom = new SecureRandom(seed.getBytes());          } else {              secureRandom = new SecureRandom();          }          keyGenerator.init(KEY_SIZE, secureRandom);           SecretKey secretKey = keyGenerator.generateKey();           return Base64Utils.encode(secretKey.getEncoded());      }            /**       * <p>       * 加密       * </p>       *        * @param data       * @param key       * @return       * @throws Exception       */      public static byte[] encrypt(byte[] data, String key) throws Exception {          Key k = toKey(Base64Utils.decode(key));          byte[] raw = k.getEncoded();           SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);           Cipher cipher = Cipher.getInstance(ALGORITHM);           cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);          return cipher.doFinal(data);      }            /**       * <p>       * 文件加密       * </p>       *        * @param key       * @param sourceFilePath       * @param destFilePath       * @throws Exception       */      public static void encryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {          File sourceFile = new File(sourceFilePath);          File destFile = new File(destFilePath);           if (sourceFile.exists() && sourceFile.isFile()) {              if (!destFile.getParentFile().exists()) {                  destFile.getParentFile().mkdirs();              }              destFile.createNewFile();              InputStream in = new FileInputStream(sourceFile);              OutputStream out = new FileOutputStream(destFile);              Key k = toKey(Base64Utils.decode(key));              byte[] raw = k.getEncoded();               SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);               Cipher cipher = Cipher.getInstance(ALGORITHM);               cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);              CipherInputStream cin = new CipherInputStream(in, cipher);              byte[] cache = new byte[CACHE_SIZE];              int nRead = 0;              while ((nRead = cin.read(cache)) != -1) {                  out.write(cache, 0, nRead);                  out.flush();              }              out.close();              cin.close();              in.close();          }      }            /**       * <p>       * 解密       * </p>       *        * @param data       * @param key       * @return       * @throws Exception       */      public static byte[] decrypt(byte[] data, String key) throws Exception {          Key k = toKey(Base64Utils.decode(key));          byte[] raw = k.getEncoded();           SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);           Cipher cipher = Cipher.getInstance(ALGORITHM);           cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);          return cipher.doFinal(data);      }            /**       * <p>       * 文件解密       * </p>       *        * @param key       * @param sourceFilePath       * @param destFilePath       * @throws Exception       */      public static void decryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {          File sourceFile = new File(sourceFilePath);          File destFile = new File(destFilePath);           if (sourceFile.exists() && sourceFile.isFile()) {              if (!destFile.getParentFile().exists()) {                  destFile.getParentFile().mkdirs();              }              destFile.createNewFile();              FileInputStream in = new FileInputStream(sourceFile);              FileOutputStream out = new FileOutputStream(destFile);              Key k = toKey(Base64Utils.decode(key));              byte[] raw = k.getEncoded();               SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);               Cipher cipher = Cipher.getInstance(ALGORITHM);               cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);              CipherOutputStream cout = new CipherOutputStream(out, cipher);              byte[] cache = new byte[CACHE_SIZE];              int nRead = 0;              while ((nRead = in.read(cache)) != -1) {                  cout.write(cache, 0, nRead);                  cout.flush();              }              cout.close();              out.close();              in.close();          }      }            /**       * <p>       * 转换密钥       * </p>       *        * @param key       * @return       * @throws Exception       */      private static Key toKey(byte[] key) throws Exception {          SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);          return secretKey;      }        }
Base64Utils.java(依赖javabase64-1.3.1.jar)

package demo.security;    import java.io.ByteArrayInputStream;  import java.io.ByteArrayOutputStream;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileOutputStream;  import java.io.InputStream;  import java.io.OutputStream;    import it.sauronsoftware.base64.Base64;    /**   * <p>   * BASE64编码解码工具包   * </p>   * <p>   * 依赖javabase64-1.3.1.jar   * </p>   *    * @author IceWee   * @date 2012-5-19   * @version 1.0   */  public class Base64Utils {        /**       * 文件读取缓冲区大小       */      private static final int CACHE_SIZE = 1024;            /**       * <p>       * BASE64字符串解码为二进制数据       * </p>       *        * @param base64       * @return       * @throws Exception       */      public static byte[] decode(String base64) throws Exception {          return Base64.decode(base64.getBytes());      }            /**       * <p>       * 二进制数据编码为BASE64字符串       * </p>       *        * @param bytes       * @return       * @throws Exception       */      public static String encode(byte[] bytes) throws Exception {          return new String(Base64.encode(bytes));      }            /**       * <p>       * 将文件编码为BASE64字符串       * </p>       * <p>       * 大文件慎用,可能会导致内存溢出       * </p>       *        * @param filePath 文件绝对路径       * @return       * @throws Exception       */      public static String encodeFile(String filePath) throws Exception {          byte[] bytes = fileToByte(filePath);          return encode(bytes);      }            /**       * <p>       * BASE64字符串转回文件       * </p>       *        * @param filePath 文件绝对路径       * @param base64 编码字符串       * @throws Exception       */      public static void decodeToFile(String filePath, String base64) throws Exception {          byte[] bytes = decode(base64);          byteArrayToFile(bytes, filePath);      }            /**       * <p>       * 文件转换为二进制数组       * </p>       *        * @param filePath 文件路径       * @return       * @throws Exception       */      public static byte[] fileToByte(String filePath) throws Exception {          byte[] data = new byte[0];          File file = new File(filePath);          if (file.exists()) {              FileInputStream in = new FileInputStream(file);              ByteArrayOutputStream out = new ByteArrayOutputStream(2048);              byte[] cache = new byte[CACHE_SIZE];              int nRead = 0;              while ((nRead = in.read(cache)) != -1) {                  out.write(cache, 0, nRead);                  out.flush();              }              out.close();              in.close();              data = out.toByteArray();           }          return data;      }            /**       * <p>       * 二进制数据写文件       * </p>       *        * @param bytes 二进制数据       * @param filePath 文件生成目录       */      public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {          InputStream in = new ByteArrayInputStream(bytes);             File destFile = new File(filePath);          if (!destFile.getParentFile().exists()) {              destFile.getParentFile().mkdirs();          }          destFile.createNewFile();          OutputStream out = new FileOutputStream(destFile);          byte[] cache = new byte[CACHE_SIZE];          int nRead = 0;          while ((nRead = in.read(cache)) != -1) {                 out.write(cache, 0, nRead);              out.flush();          }          out.close();          in.close();      }              }
AESTester.java

package demo.security;    public class AESTester {            static String key;            static {          try {   key = AESUtils.getSecretKey();          } catch (Exception e) {              e.printStackTrace();          }      }        public static void main(String[] args) throws Exception {          long begin = System.currentTimeMillis();          encryptFile();          decryptFile();          test();          long end = System.currentTimeMillis();          System.err.println("耗时:" + (end-begin)/1000 + "秒");      }            static void encryptFile() throws Exception {          String sourceFilePath = "D:/demo.mp4";          String destFilePath = "D:/demo_encrypted.mp4";          AESUtils.encryptFile(key, sourceFilePath, destFilePath);      }            static void decryptFile() throws Exception {          String sourceFilePath = "D:/demo_encrypted.mp4";          String destFilePath = "D:/demo_decrypted.mp4";          AESUtils.decryptFile(key, sourceFilePath, destFilePath);      }            static void test() throws Exception {          String source = "这是一行测试DES加密/解密的文字,你看完也等于没看,是不是啊?!";          System.err.println("原文:\t" + source);          byte[] inputData = source.getBytes();          inputData = AESUtils.encrypt(inputData, key);          System.err.println("加密后:\t" + Base64Utils.encode(inputData));          byte[] outputData = AESUtils.decrypt(inputData, key);          String outputStr = new String(outputData);          System.err.println("解密后:\t" + outputStr);      }    }
转自:http://www.blogjava.net/icewee/archive/2012/05/19/378556.html