编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

java加解密文件公用方法整合(多看一本书,少写三行代码)

wxchong 2024-07-25 13:52:39 开源技术 14 ℃ 0 评论

最近接到任务(文件的安全性)需要在文件上传到服务器上时将文件加密保存, 用户下载时将文件解密后返回给用户。翻了下方法最后决定用java中的Cipher类来完成(里面的实现方式挺全的)。

上手实现。pom.xml文件引入依赖包

<dependencies>
		<dependency>
			<groupId>org.bouncycastle</groupId>
			<artifactId>bcprov-jdk15on</artifactId>
			<version>1.56</version>
		</dependency>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.10</version>
		</dependency>
	</dependencies> 

生成秘钥(static代码块必须否则会报错)

static {
		Security.addProvider(new BouncyCastleProvider());
	}
	public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException {
		KeyGenerator kg = KeyGenerator.getInstance("AES", BouncyCastleProvider.PROVIDER_NAME);
		kg.init(128, new SecureRandom());
		byte[] result = kg.generateKey().getEncoded();
		System.out.println(new String(Hex.encodeHex(result, false)));
	}

初始化Cipher加解密的公用方法

/**
   * 
   * @param mode_type 加解密类型
   * @param keyData key的字节数组
   * @param cipher_algorith 算法/工作模式/填充模式
   * @param algorith_name 算法
   * @return
   * @throws InvalidKeyException
   * @throws NoSuchPaddingException
   * @throws NoSuchAlgorithmException
   * @throws NoSuchProviderException
   */
  public static Cipher generateCipher(int mode_type, byte[] keyData,String cipher_algorith,String algorith_name)
    throws InvalidKeyException,
    NoSuchPaddingException,
    NoSuchAlgorithmException,
    NoSuchProviderException
  {
    Cipher cipher = Cipher.getInstance(cipher_algorith, BouncyCastleProvider.PROVIDER_NAME);
    SecretKeySpec key = new SecretKeySpec(keyData, algorith_name);
    cipher.init(mode_type, key);
    return cipher;
  }

加密方法调用

 /**
   * 
   * @param key  秘钥
   * @param inStream 源文件流
   * @param targetPath 加密后文件
   * @param cipher_algorith 算法/工作模式/填充模式
   * @param algorith_name 算法
   * @throws InvalidKeyException
   * @throws NoSuchPaddingException
   * @throws NoSuchAlgorithmException
   * @throws NoSuchProviderException
   * @throws IOException
   */
  public static void encryptStream(String key, InputStream inStream, String targetPath,String cipher_algorith,String algorith_name) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, IOException
  {
    CipherInputStream cipherInputStream = null;
    try
    {
      byte[] keyData = ByteUtils.fromHexString(key);
      Cipher cipher = generateCipher(Cipher.ENCRYPT_MODE, keyData, cipher_algorith, algorith_name);
      cipherInputStream = new CipherInputStream(inStream, cipher);
      Util.copy(cipherInputStream, targetPath);
    }
    finally
    {
      Util.close(cipherInputStream,inStream);
    }
  }

解密方法调用

/**
   * 
   * @param key 秘钥
   * @param sourcePath 加密文件
   * @param out 输入的文件流
   * @param cipher_algorith 算法/工作模式/填充模式
   * @param algorith_name 算法
   * @throws InvalidKeyException
   * @throws NoSuchPaddingException
   * @throws NoSuchAlgorithmException
   * @throws NoSuchProviderException
   * @throws IOException
   */
  public static void decryptFile(String key,String sourcePath, OutputStream out,String cipher_algorith,String algorith_name) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, IOException
  {
    CipherOutputStream cipherOutputStream = null;
    try
    {
      byte[] keyData = ByteUtils.fromHexString(key);
      Cipher cipher = generateCipher(Cipher.DECRYPT_MODE, keyData, cipher_algorith, algorith_name);
      cipherOutputStream = new CipherOutputStream(out, cipher);
      Files.copy(Paths.get(sourcePath), cipherOutputStream);
    }
    finally
    {
    	Util.close(cipherOutputStream, out);
    }
  }

写个工具类用于文件转移和关流

public class Util {
	/**
	 * 文件转移 当上级目录不存在时创建
	 * 
	 * @param in
	 * @param targetPath
	 * @throws IOException
	 */
	public static void copy(InputStream in, String targetPath) throws IOException {
		Path target = Paths.get(targetPath);
		Files.createDirectories(target.getParent());
		Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
	}

	/**
	 * 关流
	 * @param cb
	 */
	public static void close(Closeable... cb) {
		for (Closeable cbd : cb) {
			if (cbd != null) {
				try {
					cbd.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

找到Cipher中支持的加解密算法,从bcprov-jdk15on1.56.jar包中翻出目前支持的算法有



找几个常用的加解密方式来验收下成果

package com.more.fw.core.common.method;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.KeyGenerator;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Test {
  public static final String ALGORITHM_NAME_3DES = "DESede";//Blowfish算法
  
  public static final String CIPHER_ALGORITHM_3DES_ECB = "DESede/ECB/PKCS5Padding";//格式是"算法/工作模式/填充模式"
  
  public static final String ALGORITHM_NAME_BLOWFISH = "Blowfish";//Blowfish算法
  
  public static final String CIPHER_ALGORITHM_BLOWFISH = "Blowfish/ECB/PKCS5Padding";//格式是"算法/工作模式/填充模式"
  
  public static final String ALGORITHM_NAME_SM4 = "SM4";//SM4算法
  
  public static final String CIPHER_ALGORITHM_SM4 = "SM4/ECB/PKCS5Padding";//格式是"算法/工作模式/填充模式"
  
  public static final String ALGORITHM_NAME_AES = "AES";//AES算法

  public static final String CIPHER_ALGORITHM_AES = "AES/ECB/PKCS5Padding";//格式是"算法/工作模式/填充模式"
  
  public static final String ALGORITHM_NAME_RC2 = "RC2";//RC2算法

  public static final String CIPHER_ALGORITHM_RC2 = "RC2/ECB/PKCS5Padding";//格式是"算法/工作模式/填充模式"
	static {
		Security.addProvider(new BouncyCastleProvider());
	}
	public static final int DEFAULT_KEY_SIZE = 128;
	public static void main(String[] args) throws Exception {
		String key = generateKey(ALGORITHM_NAME_AES);
		FileInputStream in = new FileInputStream("F:\\logs\\mc_info.log.14");//源文件
		String targer = "D:\\logs\\mc_info.log.15";//加密后文件
		long star = System.currentTimeMillis();
		encryptStream(key,in,targer,CIPHER_ALGORITHM_AES,ALGORITHM_NAME_AES);
		System.out.println("AES加密時間:"+(System.currentTimeMillis()-star));
		
		FileOutputStream out = new FileOutputStream("D:\\logs\\mc_info.log.16");
		
		star = System.currentTimeMillis();
		decryptFile(key, targer, out, CIPHER_ALGORITHM_AES,ALGORITHM_NAME_AES);
		System.out.println("AES解密時間:"+(System.currentTimeMillis()-star));
		
		in = new FileInputStream("F:\\logs\\mc_info.log.14");//源文件
		targer = "D:\\logs\\mc_info.log.17";//加密后文件
		star = System.currentTimeMillis();
		encryptStream(key,in,targer,CIPHER_ALGORITHM_SM4,ALGORITHM_NAME_SM4);
		System.out.println("SM4加密時間:"+(System.currentTimeMillis()-star));
		
		out = new FileOutputStream("D:\\logs\\mc_info.log.18");
		
		star = System.currentTimeMillis();
		decryptFile(key, targer, out, CIPHER_ALGORITHM_SM4,ALGORITHM_NAME_SM4);
		System.out.println("SM4解密時間:"+(System.currentTimeMillis()-star));
		
		in = new FileInputStream("F:\\logs\\mc_info.log.14");//源文件
		targer = "D:\\logs\\mc_info.log.19";//加密后文件
		star = System.currentTimeMillis();
		encryptStream(key,in,targer,CIPHER_ALGORITHM_BLOWFISH,ALGORITHM_NAME_BLOWFISH);
		System.out.println("BLOWFISH加密時間:"+(System.currentTimeMillis()-star));
		
		out = new FileOutputStream("D:\\logs\\mc_info.log.20");
		
		star = System.currentTimeMillis();
		decryptFile(key, targer, out, CIPHER_ALGORITHM_BLOWFISH,ALGORITHM_NAME_BLOWFISH);
		System.out.println("BLOWFISH解密時間:"+(System.currentTimeMillis()-star));
		
		in = new FileInputStream("F:\\logs\\mc_info.log.14");//源文件
		targer = "D:\\logs\\mc_info.log.21";//加密后文件
		star = System.currentTimeMillis();
		encryptStream(key,in,targer,CIPHER_ALGORITHM_3DES_ECB,ALGORITHM_NAME_3DES);
		System.out.println("3DES加密時間:"+(System.currentTimeMillis()-star));
		
		out = new FileOutputStream("D:\\logs\\mc_info.log.22");
		
		star = System.currentTimeMillis();
		decryptFile(key, targer, out, CIPHER_ALGORITHM_3DES_ECB,ALGORITHM_NAME_3DES);
		System.out.println("3DES解密時間:"+(System.currentTimeMillis()-star));

		in = new FileInputStream("F:\\logs\\mc_info.log.14");//源文件
		targer = "D:\\logs\\mc_info.log.22";//加密后文件
		star = System.currentTimeMillis();
		encryptStream(key,in,targer,CIPHER_ALGORITHM_RC2,ALGORITHM_NAME_RC2);
		System.out.println("RC2加密時間:"+(System.currentTimeMillis()-star));
		
		out = new FileOutputStream("D:\\logs\\mc_info.log.23");
		
		star = System.currentTimeMillis();
		decryptFile(key, targer, out, CIPHER_ALGORITHM_RC2,ALGORITHM_NAME_RC2);
		System.out.println("RC2解密時間:"+(System.currentTimeMillis()-star));
		
	}
	
	public static String generateKey(String algorithmName) throws Exception {
		KeyGenerator kg = KeyGenerator.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
		kg.init(DEFAULT_KEY_SIZE, new SecureRandom());
		byte[] result = kg.generateKey().getEncoded();
		return new String(Hex.encodeHex(result, false));
	}
}

跑出的结果如下

AES加密時間:6845
AES解密時間:2880
SM4加密時間:8328
SM4解密時間:4255
BLOWFISH加密時間:7648
BLOWFISH解密時間:3935
3DES加密時間:18351
3DES解密時間:14710
RC2加密時間:12116
RC2解密時間:4151

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表