Java安全编程:DES加密解密
2018-06-07 本文已影响18人
张振伟
安全
DES
- DES加密是最常用的对称加密算法之一。
- 所谓“对称加密”指的就是从明文加密到密文和从密文解密到明文用的都是相同的一套密钥与之相对应的就是“非对称加密”。
- 其它常见的对称加密算法还有IDEA、RC2、RC4、SKIPJACK、RC5、AES等。
- DES加密可以给字节数组加密,也可以给文件加密。
- 当然在加解密之前我们需要获取密钥,获取密钥可以通过我们给定的字节数组或者生成一个随机的密钥。密钥其实就是一个8个长度的字节数组。
/**
* 生成一个随机的DES密钥
* @throws Exception
*/
public static Key randomKey() throws Exception{
KeyGenerator generator = KeyGenerator.getInstance("DES");
SecretKey key = generator.generateKey();
byte[] arrKey = key.getEncoded();
System.out.println(Arrays.toString(arrKey));
System.out.println("密钥Base64转码:" + Base64.encodeBase64String(arrKey));
System.out.println("密钥16进制显示:" + Hex.encodeHexString(arrKey));
return key;
}
/**
* 根据byte数组获得密钥对象
* @param arrKey
* @return
* @throws Exception
*/
public static Key getKey(byte[] arrKey) throws Exception {
//实例化DES密钥材料
DESKeySpec spec = new DESKeySpec(arrKey);
//实例化DES密钥工厂
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
return factory.generateSecret(spec);
}
从DESKeySpec类的构造函数中可以看出,只能传入一个8位的字节数组实例化。
public DESKeySpec(byte abyte0[])
throws InvalidKeyException
{
this(abyte0, 0);
}
public DESKeySpec(byte abyte0[], int i)
throws InvalidKeyException
{
if(abyte0.length - i < 8)
{
throw new InvalidKeyException("Wrong key size");
} else
{
a = new byte[8];
System.arraycopy(abyte0, i, a, 0, 8);
return;
}
}
获得密钥后我们就可以进行字节数组和文件的加解密工作。
/**
* 加密字节数组形式的数据
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByteArr(byte[] data, Key key) throws Exception {
// using DES in ECB mode
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
/**
* 解密字节数组形式的密文
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByteArr(byte[] data, Key key) throws Exception {
// using DES in ECB mode
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
}
/**
* DES加密文件
* @param file 明文文件
* @param dest 加密后的密文文件
* @param key 密钥
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
*/
public static void encryptFile(File file, File dest, Key key)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(dest);
CipherInputStream cis = new CipherInputStream(is, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = cis.read(buffer)) > 0) {
out.write(buffer, 0, r);
}
cis.close();
is.close();
out.close();
}
/**
* DES解密文件
* @param file 需要解密的密文文件
* @param dest 解密出的明文文件
* @param key 密钥
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IOException
*/
public static void decryptFile(File file, File dest, Key key)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IOException {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(dest);
CipherInputStream cis = new CipherInputStream(is, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = cis.read(buffer)) > 0) {
out.write(buffer, 0, r);
}
cis.close();
is.close();
out.close();
}