引言
文本将介绍如何在Java中使用DES加密算法,进行文件和字符流信息的加密和解密过程。
DES算法在Java中的使用示例
DES算法
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。
DES算法目前来说,还是应用非常广泛的,用来作为对称加密的常用方法。
依赖类库
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
这里罗列了在DES加密解密中常用到的类库依赖。
在代码中使用的常量信息如下:
public static final Charset UTF8 = Charset.forName("UTF-8");
public static final String DES_ALGORITHM = "DES";
加密方法
一般来说,加解密的方法由加密和解密两个步骤组成。 首先来看一下加密的方法定义:
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
SecretKey secretKey = generateSecretKey(key);
Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
}
入口参数为,两个字节数组,输出也是字节数组。
解密方法的定义如下:
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
SecretKey secretKey = generateSecretKey(key);
Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(data);
}
输入输出类似于解密的方法,key表示秘钥信息,data是实际使用的数据信息。
其中依赖的方法generateSecretKey主要是将key转换为SecretKey, 具体的定义如下:
private static SecretKey generateSecretKey(byte[] key) throws NoSuchAlgorithmException {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key);
KeyGenerator kg = KeyGenerator.getInstance(DES_ALGORITHM);
kg.init(secureRandom);
return kg.generateKey();
}
加密和解密的拓展方法
在之前的内容中定义了加密和解密的方法,但是这些方法只是支持字节数组为参数输入;在实际的项目中,方法的入口参数可能是比较多的,所以这里针对这些方法做了一些扩展,主要是支持String类型作为入口参数,其余类型的入口参数,大家可以酌情添加:
加密的拓展方法定义:
public static byte[] encrypt(String data, String key) throws Exception {
return encrypt(data.getBytes(UTF8), key.getBytes(UTF8));
}
public static byte[] encrypt(String data, byte[] key) throws Exception {
return encrypt(data.getBytes(UTF8), key);
}
public static byte[] encrypt(byte[] data, String key) throws Exception {
return encrypt(data, key.getBytes(UTF8));
}
解密的拓展方法定义:
public static byte[] decrypt(String data, String key) throws Exception {
return decrypt(data.getBytes(UTF8), key.getBytes(UTF8));
}
public static byte[] decrypt(String data, byte[] key) throws Exception {
return decrypt(data.getBytes(UTF8), key);
}
public static byte[] decrypt(byte[] data, String key) throws Exception {
return decrypt(data, key.getBytes(UTF8));
}
测试用例
这里基于JUnit定义了一个测试用例,用以加密和解密一张图片文件,并将文件写入到本地的文件系统之中,具体的文件名称大家可以自行酌情修改,具体的代码定义如下:
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
public class DESUtilTest {
ResourceLoader loader = new DefaultResourceLoader();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test() throws Exception {
// 图片源文件
File imageFile = loader.getResource("classpath:images/spring.jpg").getFile();
byte[] bytes = FileUtils.readFileToByteArray(imageFile);
String key = "no bodyre about this";
System.out.println("original file size:" + bytes.length);
for (int i=0;i<2; i++) {
long startTime = System.currentTimeMillis();
byte[] encodedBytes = DESUtil.encrypt(bytes, key);
byte[] decodedBytes = DESUtil.decrypt(encodedBytes, key);
System.out.println("Time Consumed:" + (System.currentTimeMillis() - startTime));
System.out.println("Encoded Key:" + encodedBytes.length + " vs DecodedKey:" + decodedBytes.length);
# 图片加密的文件
FileUtils.writeByteArrayToFile(new File("C:\TodolistEncoded.jpg"), encodedBytes);
# 图片解密的文件
FileUtils.writeByteArrayToFile(new File("C:\TodolistDncoded.jpg"), decodedBytes);
}
}
}
这里的ResourceLoader是Spring中提供的用以读取classpath下文件的一个加载器,路径可以使用classpath:开头的任意路径,而无需依赖于本地文件系统的绝对路径,是非常好用的。
大家可以自行运行,并修改上述测试代码。
总结
DES是一种最为简单的对称加密方法, 3DES是其增强版本,这里演示了其使用的方法,加密和解密的代码,以及相关的测试代码。方便大家后续进行参考。
关于我自己
这些技巧和总结都是来自于实际的工作,欢迎大家反馈和提出自己的意见。
文章也会同步发在今日头条的头条号上,搜索 “程序加油站”,就可以找到。