暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

3DES加密

笔记有云 2021-05-08
436

前情提要

    近期在研究京东支付的时候遇到了"3DES"加密的方法,那么什么是3DES加密呢,今天就来了解一下。

    百度百科介绍如下:

    3DES又称Triple DES,是DES加密算法的一种模式,它使用2条不同的56位的密钥对数据进行三次加密。

    数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。

    DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:

3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1(EK2(Dk3(C)))

Java实现

//温馨提示:代码较多,可向右滑动查看代码
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;


public class ThreeDesUtil {
public static final byte[] DEFAULT_KEY = {
49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52};


public static byte[] encrypt(byte[] keybyte, byte[] src) {
try {
            SecretKey deskey = new SecretKeySpec(keybyte, "DESede");
Cipher c1 = Cipher.getInstance("DESede/ECB/NoPadding");
c1.init(1, deskey);
return c1.doFinal(src);
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (Exception e3) {
e3.printStackTrace();
}
return null;
}


private static byte[] decrypt(byte[] keybyte, byte[] src) {
try {
            SecretKey deskey = new SecretKeySpec(keybyte, "DESede");
Cipher c1 = Cipher.getInstance("DESede/ECB/NoPadding");
c1.init(2, deskey);
return c1.doFinal(src);
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (Exception e3) {
e3.printStackTrace();
}
return null;
}


private static String byte2Hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
if (n < b.length - 1) hs = hs + ":";
}
return hs.toUpperCase();
}


public static String encrypt2HexStr(byte[] keys, String sourceData) {
try {
byte[] source = sourceData.getBytes("UTF-8");
int merchantData = source.length;
int x = (merchantData + 4) % 8;
int y = (x == 0) ? 0 : (8 - x);
byte[] sizeByte = intToByteArray(merchantData);
byte[] resultByte = new byte[merchantData + 4 + y];
resultByte[0] = sizeByte[0];
resultByte[1] = sizeByte[1];
resultByte[2] = sizeByte[2];
resultByte[3] = sizeByte[3];
for (int i = 0; i < merchantData; i++) {
resultByte[4 + i] = source[i];
}
for (int i = 0; i < y; i++) {
resultByte[merchantData + 4 + i] = 0;
}
byte[] desdata = encrypt(keys, resultByte);
return bytes2Hex(desdata);
} catch (UnsupportedEncodingException e) {
            e.printStackTrace();
return null;
}
}


public static String decrypt4HexStr(byte[] keys, String data) {
byte[] hexSourceData = new byte[0];
try {
hexSourceData = hex2byte(data.getBytes("UTF-8"));
byte[] unDesResult = decrypt(keys, hexSourceData);
byte[] dataSizeByte = new byte[4];
dataSizeByte[0] = unDesResult[0];
dataSizeByte[1] = unDesResult[1];
dataSizeByte[2] = unDesResult[2];
dataSizeByte[3] = unDesResult[3];
int dsb = byteArrayToInt(dataSizeByte, 0);
if (dsb > 16384) {
throw new RuntimeException("msg over MAX_MSG_LENGTH or msg error");
}
byte[] tempData = new byte[dsb];
for (int i = 0; i < dsb; i++) {
tempData[i] = unDesResult[4 + i];
}
return hex2bin(toHexString(tempData));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}


private static String hex2bin(String hex) throws UnsupportedEncodingException {
String digital = "0123456789abcdef";
char[] hex2char = hex.toCharArray();
        byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
int temp = digital.indexOf(hex2char[2 * i]) * 16;
temp += digital.indexOf(hex2char[2 * i + 1]);
bytes[i] = (byte) (temp & 0xFF);
        }
return new String(bytes, "UTF-8");
}


private static String toHexString(byte[] ba) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < ba.length; i++) {
str.append(String.format("%x", new Object[]{Byte.valueOf(ba[i])}));
}
return str.toString();
}


private static String bytes2Hex(byte[] bts) {
String des = "";
String tmp = null;
for (int i = 0; i < bts.length; i++) {
tmp = Integer.toHexString(bts[i] & 0xFF);
if (tmp.length() == 1) {
des = des + "0";
}
des = des + tmp;
}
return des;
}


public static byte[] hex2byte(byte[] b) {
if (b.length % 2 != 0) {
throw new IllegalArgumentException("长度不是偶数");
}
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
            String item = new String(b, n, 2);
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
b = null;
return b2;
}


private static byte[] intToByteArray(int i) {
byte[] result = new byte[4];
result[0] = (byte) (i >> 24 & 0xFF);
result[1] = (byte) (i >> 16 & 0xFF);
result[2] = (byte) (i >> 8 & 0xFF);
result[3] = (byte) (i & 0xFF);
return result;
}


private static int byteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (3 - i) * 8;
value += ((b[i + offset] & 0xFF) << shift);
}
return value;
}
}

【更多精彩】

脚本搭建Nginx、Redis、MySql、Maven

Java获取小程序手机号码

Java微信小程序支付

MyBatisPlus代码生成器配置

文章转载自笔记有云,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论