DES與3DES加解密
阿新 • • 發佈:2018-12-11
一、DES和3DES的概念
二、需求背景
我們在線上經常使用DES加密使用者id,以下簡稱(encodeId),後端傳個前端,前端會使用localStorage儲存encodeId,然後呼叫介面時將encodeId作為入參,後端通過encodeId區分每個使用者,返回前端相應資料,但是DES加密有被破解的報道,現在使用3DES對使用者id,省份證號等敏感資訊進行加解密,暫時沒有被攻破的記錄,3DES比DES更安全。對於常用的DES和3DES線上封裝一般都是下面這樣。(僅供參考)
三、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 = "[email protected]#$y1a2n.&@[email protected]
$%*(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包
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
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 = "[email protected]#$y1a2n.&@[email protected]$%*(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