Java安全知识汇总:对称加密
引用转载请注明出处,Thanks!
- BASE64加密
- DES加密
一、BASE64加密
简介:Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。[2]
- 使用BASE64加密
使用BASE64Encoder类的encodeBuffer()方法,产生一个String类型的返回值,即可得加密后的字符。
import sun.misc.BASE64Encoder;
public class BASE64Test {
public static void main(String[] args) {
String data = "csdn博客";
System.out.println("加密前:"+ data);
BASE64Encoder be = new BASE64Encoder();
String data2 = be.encodeBuffer(data.getBytes());
System.out.println("加密后:"+ data2);
}
}
输出:
加密前:csdn博客
加密后:Y3NkbrKpv80=
备注:使用BASE64加密后的字符串个数都是4的倍数,一个字符占两个字节,也就是说BASE64加密以后的字符串必须是8个字节的倍数,如果不足,需要在后面补上”=”。[1]
- 使用BASE64解密
import java.io.IOException;
import sun.misc.BASE64Decoder;
public class BASE64Test2 {
public static void main(String[] args) {
String data = "Y3NkbrKpv80=";
System.out.println("加密字符:"+ data);
BASE64Decoder bd = new BASE64Decoder();
byte[] data2 = null;
try {
data2 = bd.decodeBuffer(data);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("加密后:"+ new String(data2));
}
}
输出:
加密字符:Y3NkbrKpv80=
加密后:csdn博客
二、DES加密
简介:DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。[3]
DES加密需要先生成一个密钥,加密端通过该密钥进行加密,解密时,解密的一端也需要使用该密钥对数据解密,密钥生成以后是byte[]类型的数据,这种加密手段也称为对称加密。
- 生成DES的密钥
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class DESTest {
public static void main(String[] args) {
DESTest dt = new DESTest();
dt.initKey();
}
/**
* 生成DES密钥,并保存到文件中
*/
public void initKey(){
//产生一个随机数源
SecureRandom secureRandom = new SecureRandom();
//为DES算法生成一个KeyGenerator
KeyGenerator generator;
try {
generator = KeyGenerator.getInstance("DES");
generator.init(secureRandom);
SecretKey key = generator.generateKey();
//生成密钥数据保存到文件中
writeFile(key.getEncoded(), "KeyData.dat");
System.out.println("密钥生成完成,存放在项目根目录中");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 将生成的byte[] 数据存到文件中
* @param data DES生成的密钥
* @param fileName 存放文件名
*/
public void writeFile(byte[] data,String fileName){
try {
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
fileOutputStream.write(data);
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
- 使用DES加密
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DESTest2 {
/**
* 读取存放的DES密钥文件并返回byte[]
* @param fileName
* @return byte[]
*/
public byte[] readFile(String fileName){
try {
//创建文件
File file = new File(fileName);
//创建文件输入流
FileInputStream fileInputStream = new FileInputStream(file);
byte[] data = new byte[(int)file.length()];
fileInputStream.read(data);
fileInputStream.close();
return data;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e2){
e2.printStackTrace();
}
return null;
}
/**
* 使用DESKeySpec和SecretKeyFactory类把密钥数据转换为密钥对象
* @return DES Key
*/
public Key toKey(){
try {
byte[] key = readFile("keyData.dat");
DESKeySpec keySpec = new DESKeySpec(key);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
//转化密钥成key进行加密解密
SecretKey secretKey = factory.generateSecret(keySpec);
return secretKey;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e){
e.printStackTrace();
} catch (InvalidKeySpecException e){
e.printStackTrace();
}
return null;
}
/**
* 加密
* @param data
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public void encrypt(byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
Key key = toKey();
//使用Cipher实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//使用密钥初始化Cipher
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] f = cipher.doFinal(data);
//调用writeFile,存下加密后的文件
DESTest dt = new DESTest();
dt.writeFile(f, "fileData.dat");
}
public static void main(String[] args) {
try {
DESTest2 dt2 = new DESTest2();
String data = "csdn博客";
//调用encrypt进行加密
dt2.encrypt(data.getBytes());
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
}
- 使用DES解密
首先清楚,密钥保存在项目根目录的keyData.dat中,加密后的文件保存在fileData.data中。
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class DESTest3 {
/**
* 解密
* @return
*/
public String decrypt(){
//获得保存的密钥
DESTest2 dt2 = new DESTest2();
Key key = dt2.toKey();
try {
Cipher cipher = Cipher.getInstance("DES");
//初始化
cipher.init(Cipher.DECRYPT_MODE, key);
//读取到加密后的文件
byte[] f = dt2.readFile("fileData.dat");
//解密
byte[] f2 = cipher.doFinal(f);
return new String(f2);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
DESTest3 dt3 = new DESTest3();
String data = dt3.decrypt();
System.out.println("解密后的数据是:"+ data);
}
}
结果为:解密后的数据是:csdn博客
引用:
[注释1]:JAVA开发实战1200例(第二卷)
[注释2]:百度百科:https://baike.baidu.com/item/base64/8545775?fr=aladdin
[注释3]:百度百科:https://baike.baidu.com/item/DES/210508?fr=aladdin