最近接到任务(文件的安全性)需要在文件上传到服务器上时将文件加密保存, 用户下载时将文件解密后返回给用户。翻了下方法最后决定用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
本文暂时没有评论,来添加一个吧(●'◡'●)