java中的加密与解密方法
在企业级的开发中,我们经常要涉及到对数据的加密与解密处理,如常见的密码,订单号,附件标识,银行卡号等等,接下来这篇文章笔者就给大家分享一个封装好的加密与解密方法。
加密:在java中,我们通常使用Cipher类来进行加解密处理,当其加密之时我们传给其参数是(密钥,加密类型),然后再将需要加密的数据源加密之后返回一个byte[](字节数组),然后我们通过对这个byte[]进行处理,得到一个加密后的字符串。
解密:将加密后的字符串以及密钥一起传入再转换成解密之后的数据返回来。
我们这里使用的是DES加解密算法
加解密的方法唯一的不同是在Cipher对象初始化init()方法是调用的参数是解密参数ENCRYPT_MODE= 1
/*
*加密
*value 数据源转化的字节数组
*key 密钥,长度要8的倍数
* return 返回一个字节数组
*/
public static byte[] encrypt(byte[] value,byte[] key){
//DES算法首先要创建一个可信任的随机数源
SecureRandom sr = new SecureRandom();
//根据DES密钥创建一个DESkeySpec对象
DESKeySpec dks =new DESKeySpec(key);
//创建一个DES算法的密钥工厂对象
SecretKeyFactory keyFactory = SecretKeyFactory.geyInstance("DES");
//得到一个SecretKey 对象,基于DES算法的密钥工厂创建
SecretKey secretKey = keyFactory.generateSecret(dks);
/*
*这个SecretKey对象就是根据DES算法生成的一把锁,同时也需要用DES来生成一把钥匙才可以打开的
*/
//开始创建Cipher类来对数据源进行加密了,基于DES创建的Cipher对象
Cipher cipher = Cipher.getInstance("DES");
//初始化cipher对象,封装信息(ENCRYPT_MODE=1代表的是加密)
cipher.init(Cip.ENCRYPT_MODE,secretKey,sr);
//加密操作
//获取数据
return cipher.doFinal(value);
}
将加密后的字节数组封装成一个String的字符串
/*
*将Cipher加密后的字节数组转化成String
*/
public static String byteToString (byte[] b){
//创建加密后的字符串
String encryptString= "";
//单个字节转化成字符串
String oneByte = "";
for(int n = 0;n<b.length;n++){
//toHexString 方法是将Byte类型的字节转化成String类型
/*
*&XFF的问题是为了将负数转变成正数
*具体问题可以阅读我下篇博客,涉及到了二进制,十进制,十六进制,原码和补码的问题。
*https://blog.csdn.net/fei476662546/article/details/108831700
*/
oneByte = (java.lang.Integer.toHexString(b[n] & 0XFF))
//如果只有一个字符,则添加‘0’
if(oneByte.length()==1){
encryptString = encryptString + oneByte+ "0";
}else{
encryptString = encryptString + oneByte;
}
}
//转化成小写返回
return encryptString.toUpperCase();
}
针对&0XFF的原因分析在这里:https://blog.csdn.net/fei476662546/article/details/108831700
解密的方法,和加密的方法几乎一样,唯一的不同是在Cipher对象初始化init()方法是调用的参数是解密参数DECRYPT_MODE=2
/*
*解密
*value 加密过后转化的字节数组
*key 密钥,长度要8的倍数
* return 返回一个字节数组
*/
public static byte[] decrypt(byte[] value,byte[] key){
//DES算法首先要创建一个可信任的随机数源
SecureRandom sr = new SecureRandom();
//根据DES密钥创建一个DESkeySpec对象
DESKeySpec dks =new DESKeySpec(key);
//创建一个DES算法的密钥工厂对象
SecretKeyFactory keyFactory = SecretKeyFactory.geyInstance("DES");
//得到一个SecretKey 对象,基于DES算法的密钥工厂创建
SecretKey secretKey = keyFactory.generateSecret(dks);
/*
*这个SecretKey对象就是根据DES算法生成的一把锁,同时也需要用DES来生成一把钥匙才可以打开的
*/
//开始创建Cipher类来对数据源进行加密了,基于DES创建的Cipher对象
Cipher cipher = Cipher.getInstance("DES");
//初始化cipher对象,封装信息,(ENCRYPT_MODE=2代表的是解密)
cipher.init(Cip.DECRYPT_MODE,secretKey,sr);
//加密操作
//获取数据
return cipher.doFinal(value);
}
将解密后的字节数组再还原成加密之前的数据源字节数组返回
public static byte[] byteToEncrypt(byte[] b){
if(b.length%2==0){
//因为加密是把一个字节转化成了2个字符,所以解密时只需要创建1/2的字节空间
byte[] b2 = new byte[b.length/2];
for(int n = 0; n<b.length; n+=2){
//将字节数组b的第n个元素和n+1个元素转化为一个字符串
//String(byte[],从第几个开始,取几个元素)
String item =new String(b,n,2);
//再将字符串通过16进制转化为Integer类型,然后在转化为byte类型
b2[n/2] = (byte) Integer.parseInt(item,16);
}
return b2;
}else{
throw new IllegalArgumentException("长度不是偶数")
}
}
封装成可以外部直接调用的加解密方法如下:
public class DncryptUtil{
//自定义一个加解密钥匙
private final static String PASSWORD_KEY="password_encrypt";
/*
*加密
*/
public final static String encrypt(String password,String key){
try{
return byteToString (encrypt(password.getBytes(),key.getBytes()));
}catch(Exception e){
}
return null ;
}
/*
*解密,加密和解密的key必须相同(也可以将key当成常量,如PASSWORD_KEY)
*/
public final static String encrypt(String password,String key){
try{
return new String(decryptby(teToEncrypt(DncryptUtil.trimToEmpty(data.getBytes()),key.getBytes()));
}catch(Exception e){
}
return null ;
}
//如果字符串为空就返回“”;
public static String trimToEmpty(String str){
return (str == null?"":str.trim());
}
}
好了,整个步骤包括源码都在这了,如果有什么疑问欢迎留言,笔者会第一时间给你解答。