为啥用到了这两种加密
DES和AES两种双向加密的实现,实现起来比较好写。
可能会问,为什么还有更多加密等级更高的或者不对等加密的算法,为什么不用那些呢?
其中一个原因是,我这边服务的客户水平不一,但已经做到这个程度的加密往往对于他们已经足够。
所以降低一些开发成本,用极可能简单好解释的策略,可以让客户快速理解并实现就更重要了。毕竟项目中尽快联调开发完成还是非常非常重要的。
当然如果客户追求安全度,那么日后我会写贴另一段代码去实现。
本文先只写这两个相对简单好写的加密方式。
直接上代码,带实例
1、DES加解密
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
public class DES {
/**
* 加密
*
* @param datasource byte[]
* @param password String
* @return byte[]
*/
public static byte[] encrypt(byte[] datasource, String password) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
return cipher.doFinal(addZero(datasource));
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param src byte[]
* @param password String
* @return byte[]
* @throws Exception
*/
public static byte[] decrypt(byte[] src, String password) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec((password.getBytes()));
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
return cipher.doFinal(src);
}
public static byte[] addZero(byte[] data) {
byte[] dataByte = data;
if (data.length % 8 != 0) {
byte[] temp = new byte[8 - data.length % 8];
dataByte = byteMerger(data, temp);
}
return dataByte;
}
// java 合并两个byte数组
// System.arraycopy()方法
public static byte[] byteMerger(byte[] bt1, byte[] bt2) {
byte[] bt3 = new byte[bt1.length + bt2.length];
System.arraycopy(bt1, 0, bt3, 0, bt1.length);
System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
return bt3;
}
/**
* byte数组转hex
*
* @param bytes
* @return
*/
public static String byteToHex(byte[] bytes) {
String strHex = "";
StringBuilder sb = new StringBuilder("");
for (int n = 0; n < bytes.length; n++) {
strHex = Integer.toHexString(bytes[n] & 0xFF);
sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0
}
return sb.toString().trim();
}
/**
* @param src 16进制字符串
* @return 字节数组
* @throws
* @Title:hexString2Bytes
* @Description:16进制字符串转字节数组
*/
public static byte[] hexString2Bytes(String src) {
int l = src.length() / 2;
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
ret[i] = Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
}
return ret;
}
}
2、DES加解密实例:
import org.apache.commons.lang3.RandomStringUtils;
import java.util.UUID;
public class Test {
public static void main(String[] args) throws Exception {
String token = UUID.randomUUID().toString().replace("-", "");
String password = RandomStringUtils.randomAlphanumeric(8);
String encodingToken = DES.byteToHex(DESUtils.encrypt(DES.hexString2Bytes(token), password));
String decodingToken = DES.byteToHex(DESUtils.decrypt(DES.hexString2Bytes(encodingToken), password));
}
}
3、AES加解密
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class AES {
private static final String AES = "AES";
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
public static String decodeStr(String content, String key) throws Exception {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), AES);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, skey);
byte[] output = cipher.doFinal(Base64.decodeBase64(content));
return new String(output);
}
public static String encodeStr(String content, String key) throws Exception {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), AES);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, skey);
byte[] output = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(output);
}
}
4、AES加解密实例
import org.apache.commons.lang3.RandomStringUtils;
import java.util.UUID;
public class Test {
public static void main(String[] args) throws Exception {
String token = UUID.randomUUID().toString().replace("-", "");
String key = RandomStringUtils.randomAlphanumeric(8);
String encodingToken = AES.encodeStr(token, key);
String decodingToken = AES.decodeStr(encodingToken, key);
}
}