· 3DES算法简介
3DES又称Triple DES,是DES加密算法的一种模式,它使用两条不同的56位密钥对数据进行三次加密。
DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。相对DES,3DES更为安全。
3DES是DES向AES过渡的加密算法,其具体实现如下:
设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:
· 3DES加密过程为:C=Ek3(Dk2(Ek1(M)))。
· 3DES解密过程为:M=Dk1(Ek2(Dk3©))。
关于3DES概念性的内容不做过多介绍,大家可以自行百度。
· Maven 依赖
工具类对于加密后使用Base64进行编码,所以需要依赖Apache Commons Codec。
<dependency>
<groupId>commons-codecgroupId>
<artifactId>commons-codecartifactId>
<version>1.9version>
dependency>
· 工具类实现
package com.arhorchin.securitit.enordecryption.des;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
/**
* @author Securitit.
* @note 3DES加解密工具类.
*/
public class TripleDESUtil {
/**
* logger.
*/
private static Logger logger = Logger.getLogger(TripleDESUtil.class);
/**
* 初始向量.
*/
public static byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
/**
* 字符串加密.
* @param encodeStr.
* @param desKey.
* @return .
*/
public static String strEncode(String encodeStr, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] strData = encodeStr.getBytes("UTF-8");
byte[] encodedStr = des3EncodeCBC(key, keyiv, strData);
return Base64.encodeBase64String(encodedStr);
} catch (Exception ex) {
logger.error("TripleDESUtil.strEncode.", ex);
return "";
}
}
/**
* 字符串解密.
* @param decodeStr.
* @param desKey.
* @return .
*/
public static String strDecode(String decodeStr, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] decodedStr = Base64.decodeBase64(decodeStr);
decodedStr = des3DecodeCBC(key, keyiv, decodedStr);
String dcoding = new String(decodedStr, "UTF-8");
return dcoding;
} catch (Exception ex) {
logger.error("TripleDESUtil.strDecode.", ex);
return "";
}
}
/**
* 字符串加密.URL安全.
* @param encodeStr.
* @param desKey.
* @return .
*/
public static String strSafeEncode(String encodeStr, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] strData = encodeStr.getBytes("UTF-8");
byte[] encodedStr = des3EncodeCBC(key, keyiv, strData);
return Base64.encodeBase64URLSafeString(encodedStr);
} catch (Exception ex) {
logger.error("TripleDESUtil.strSafeEncode.", ex);
return "";
}
}
/**
* 字符串解密.URL安全.
* @param decodeStr.
* @param desKey.
* @return .
*/
public static String strSafeDecode(String decodeStr, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] decodedStr = Base64.decodeBase64(decodeStr);
decodedStr = des3DecodeCBC(key, keyiv, decodedStr);
String dcoding = new String(decodedStr, "UTF-8");
return dcoding;
} catch (Exception ex) {
logger.error("TripleDESUtil.strSafeDecode.", ex);
return "";
}
}
/**
* 文件流解密.
* @param srcBytes.
* @param desKey.
* @return .
*/
public static byte[] byteEncode(byte[] srcBytes, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] str5 = des3EncodeCBC(key, keyiv, srcBytes);
return str5;
} catch (Exception ex) {
logger.error("TripleDESUtil.byteEncode.", ex);
return null;
}
}
/**
* 文件流加密.
* @param srcBytes.
* @param desKey.
* @return .
*/
public static byte[] byteDecode(byte[] srcBytes, String desKey) {
try {
byte[] key = Base64.decodeBase64(desKey);
byte[] str6 = des3DecodeCBC(key, keyiv, srcBytes);
return str6;
} catch (Exception ex) {
logger.error("TripleDESUtil.byteDecode.", ex);
return null;
}
}
/**
* 使用2DES加密数据.
* @param key
* @param keyiv.
* @param data.
* @return .
* @throws Exception.
*/
public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(1, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* 使用3DES解密数据.
* @param key.
* @param keyiv.
* @param data.
* @return .
* @throws Exception.
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(2, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
}
· 测试类如下
package com.arhorchin.securitit.enordecryption.des;
import java.util.UUID;
/**
* @author Securitit.
* @note TripleDESUtil测试类.
*/
public class TripleDESUtilTester {
public static void main(String[] args) {
// 随机一个32位串作为秘钥.
String desKey = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
String plainText = "This is a 3des plain text";
String cipherText = null;
// 数据加密.
cipherText = TripleDESUtil.strEncode(plainText, desKey);
System.out.println("加密密文:" + cipherText);
// 数据解密.
plainText = TripleDESUtil.strDecode(cipherText, desKey);
System.out.println("解密明文:" + plainText);
}
}
· 测试输出结果:
加密密文:kpEsLA2uoM74pUkTuDowUpvYQad9CrDsy1NGc3qL0VM=
解密明文:This is a 3des plain text
· 总结:
算法实现都很类似,本文只是对算法实现做了整理,在Maven依赖引入的情况下,TripleDESUtil已经做了简单测试,可以直接使用。