我们在线上经常使用DES加密用户id,以下简称(encodeId),后端传个前端,前端会使用localStorage保存encodeId,然后调用接口时将encodeId作为入参,后端通过encodeId区分每个用户,返回前端相应数据,但是DES加密有被破解的报道,现在使用3DES对用户id,省份证号等敏感信息进行加解密,暂时没有被攻破的记录,3DES比DES更安全。对于常用的DES和3DES线上封装一般都是下面这样。(仅供参考)
1、DESUtils
所使用的jar包都是JDK8自带的,不需要其它依赖。
package com.cn.dl.utils;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DESUtils {
//秘钥
private static final String KEY = "~@#$y1a2n.&@+n@$%*(1)";
//加密算法
private static final String ALGORITHM = "DES";
//编码
private static final String CHARSET = "UTF-8";
/**
* byte数组转换成十六进制字符串
* @param bytes byte数组
* @return
*/
private static String bytesToHexStr(byte[] bytes) {
String tmp = "";
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < bytes.length; i++) {
tmp = Integer.toHexString(bytes[i] & 0xFF);
sb.append((tmp.length() == 1) ? "0" + tmp : tmp);
}
return sb.toString().toUpperCase().trim();
}
/**
* 十六进制字符串转成byte数组
* @param hexStr 十六进制字符串
* @return
* */
private static byte[] hexStrToBytes(String hexStr) {
byte[] bytes = new byte[hexStr.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hexStr.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
/**
* @param key 秘钥
* @param encodeStr 需要加密的字符串
* @return
*/
public static String encodeDES(String key, String encodeStr) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(new DESKeySpec(key.getBytes()));
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(encodeStr.getBytes(CHARSET));
return bytesToHexStr(encrypted);
}
/**
* @param key 秘钥
* @param decodeStr 需要解密的字符串
* @return
*/
public static String decodeDES(String key, String decodeStr) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(new DESKeySpec(key.getBytes()));
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decodedString = cipher.doFinal(hexStrToBytes(decodeStr));
return new String(decodedString, CHARSET);
}
public static void main(String[] args) throws Exception {
String userId = "13240115";
String encode = DESUtils.encodeDES(KEY, userId);
String decode = DESUtils.decodeDES(KEY, encode);
System.out.println("用户id>>>"+userId);
System.out.println("用户id加密>>>"+encode);
System.out.println("用户id解密>>>"+decode);
}
}
测试结果:
用户id>>>13240115
用户id加密>>>62BBE8100F9C6E5E6438C40FCC3B03DA
用户id解密>>>13240115
2、DESedeUtil
需要引入jar包
commons-codec
commons-codec
1.11
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
/**
* 3DES加密算法,主要用于加密用户id,身份证号等敏感信息,防止破解
* Created by yanshao on 2018/12/10.
*/
public class DESedeUtil {
//秘钥
private static final String KEY = "~@#$y1a2n.&@+n@$%*(1)";
//秘钥长度
private static final int secretKeyLength = 24;
//加密算法
private static final String ALGORITHM = "DESede";
//编码
private static final String CHARSET = "UTF-8";
/**
* 转换成十六进制字符串
* @param key
* @return
*/
public static byte[] getHex(String key){
byte[] secretKeyByte = new byte[24];
try {
byte[] hexByte;
hexByte = new String(DigestUtils.md5Hex(key)).getBytes(CHARSET);
//秘钥长度固定为24位
System.arraycopy(hexByte,0,secretKeyByte,0,secretKeyLength);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return secretKeyByte;
}
/**
* 生成密钥,返回加密串
* @param key 密钥
* @param encodeStr 将加密的字符串
* @return
*/
public static String encode3DES(String key,String encodeStr){
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(getHex(key), ALGORITHM));
return Base64.encodeBase64String(cipher.doFinal(encodeStr.getBytes(CHARSET)));
}catch(Exception e){
e.printStackTrace();
}
return null;
}
/**
* 生成密钥,解密,并返回字符串
* @param key 密钥
* @param decodeStr 需要解密的字符串
* @return
*/
public static String decode3DES(String key, String decodeStr){
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(getHex(key),ALGORITHM));
return new String(cipher.doFinal(new Base64().decode(decodeStr)),CHARSET);
} catch(Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String userId = "13240115";
String encode = DESedeUtil.encode3DES(KEY, userId);
String decode = DESedeUtil.decode3DES(KEY, encode);
System.out.println("用户id>>>"+userId);
System.out.println("用户id加密>>>"+encode);
System.out.println("用户id解密>>>"+decode);
}
}
测试结果:
用户id>>>13240115
用户id加密>>>bv6ZVR6KAunqORpY1fpOwQ==
用户id解密>>>13240115