这两天做项目需要和.net 平台做通信,他们使用的加密是3DES,互联网上比较常见的一些算法,J2EE平台无法公用,只有自己写一个,给有需要的朋友一个参考
package com.uninf.video.util.encryption;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* 3DES 加密解密算法,用于拓荒族通信 http://www.tuohuangzu.com
*
* @author zhangwei
*
*
* @time 2013-1-29 上午8:53:23
*
*/
public class DES3Tools {
Logger log = LoggerFactory.getLogger(DES3Tools.class);
byte[] encryptKey;
DESedeKeySpec spec;
SecretKeyFactory keyFactory;
SecretKey theKey;
Cipher cipher;
IvParameterSpec IvParameters;
/**
* 字符串转换为byte数组
*
* @param str
* @return
*/
public byte[] StringToByte(String str) {
char[] ch = str.toUpperCase().toCharArray();
byte[] newBytes = new byte[str.length() / 2];
for (int i = 0; i < newBytes.length; i++) {
newBytes[i] = (byte) (Char2Hex(ch[i * 2]) * (0x10) + Char2Hex(ch[i * 2 + 1]));
}
return newBytes;
}
/**
* 字符与16进制转换
*
* @param chr
* @return
*/
private byte Char2Hex(char chr) {
switch (chr) {
case '0':
return 0x00;
case '1':
return 0x01;
case '2':
return 0x02;
case '3':
return 0x03;
case '4':
return 0x04;
case '5':
return 0x05;
case '6':
return 0x06;
case '7':
return 0x07;
case '8':
return 0x08;
case '9':
return 0x09;
case 'A':
return 0x0a;
case 'B':
return 0x0b;
case 'C':
return 0x0c;
case 'D':
return 0x0d;
case 'E':
return 0x0e;
case 'F':
return 0x0f;
}
return 0x00;
}
/**
* 初始化3des加密工具类
*/
public DES3Tools() {
try {
// 检测是否有 TripleDES 加密的供应程序
// 如无,明确地安装SunJCE 供应程序
try {
cipher = Cipher.getInstance("DESede");
} catch (Exception e) {
log.error("Installling SunJCE provider.");
Provider sunjce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunjce);
}
// 创建一个密钥 24位以上的Key
encryptKey = StringToByte(EncryptConfig.DES3_KEY);
// 为上一密钥创建一个指定的 DESSede key
spec = new DESedeKeySpec(encryptKey);
// 得到 DESSede keys
keyFactory = SecretKeyFactory.getInstance("DESede");
// 生成一个 DESede 密钥对象
theKey = keyFactory.generateSecret(spec);
// 创建一个 DESede 密码
cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
// 为 CBC 模式创建一个用于初始化的 vector 对象
IvParameters = new IvParameterSpec(
StringToByte(EncryptConfig.DES3_IV));
} catch (Exception exc) {
// 记录加密或解密操作错误
log.error("Constructor error :" + exc.getMessage());
}
}
/**
* 加密算法
*
* @param arg
* 等待加密的密码
* @return 加密以后的密码
* @throws Exception
*/
public byte[] encrypt(String arg) {
String encrypted_args = null;
byte[] encrypted_argb = null;
try {
// 以加密模式初始化密钥
cipher.init(Cipher.ENCRYPT_MODE, theKey, IvParameters);
// 加密前的密码(旧)
byte[] plainttext = arg.getBytes();
// 加密密码
encrypted_argb = cipher.doFinal(plainttext);
// 转成字符串,得到加密后的密码(新)
encrypted_args = new String(encrypted_argb);
} catch (Exception ex) {
// 记录加密错误
log.error("encrypt error : " + ex.getMessage());
}
return encrypted_argb;
}
/**
* 解密算法
*
* @param argb
* 加过密的密码
* @return 解密后的密码
*/
public String decrypt(byte[] argb) {
String decrypted_args = null;
try {
// 以解密模式初始化密钥
cipher.init(Cipher.DECRYPT_MODE, theKey, IvParameters);
// 构造解密前的密码
byte[] decryptedPassword = argb;
// 解密密码
byte[] decrypted_pwd = cipher.doFinal(decryptedPassword);
// 得到结果
decrypted_args = new String(decrypted_pwd);
} catch (Exception ex) {
// 记录解密错误
}
return decrypted_args;
}
/**
* byte 数组返回字符串
*
* @param arrB
* @return
*/
public String byteArr2HexStr(byte[] arrB) {
int iLen = arrB.length;
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
StringBuffer sb = new StringBuffer(iLen * 2);
for (int i = 0; i < iLen; i++) {
int intTmp = arrB[i];
// 把负数转换为正数
while (intTmp < 0) {
intTmp = intTmp + 256;
}
// 小于0F的数需要在前面补0
if (intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
/**
* 字符串转换byte数组
*
* @param strIn
* @return
*/
public byte[] hexStr2ByteArr(String strIn) {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i = i + 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}
/**
* base64 加密
*
* @param argb
* @return
*/
public String base64Encode(byte[] argb) {
return new BASE64Encoder().encode(argb);
}
/**
* base64 解密
*
* @param args
* @return
* @throws IOException
*/
public byte[] base64DEcode(String args) {
byte[] bytes = null;
try {
bytes = new BASE64Decoder().decodeBuffer(args);
} catch (IOException e) {
log.error("base64decoder error :" + e.getMessage());
}
return bytes;
}
/**
* 生成验证字符串
*
* @param args
* @return
*/
public String getGarbleString(String args) {
byte[] plainText = null;
try {
plainText = args.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
messageDigest.update(plainText);
byte[] digest = messageDigest.digest();
String newStr = base64Encode(digest);
return newStr;
}
/**
* 验证字符串
*
* @return
*/
public boolean verifyString(String[] args) {
if (args.length != 2) {
return false;
} else {
return getGarbleString(args[0]).equals(args[1]);
}
}
/**
* 3des 通信最终加密工具
*
* @param plainText
* @return
*/
public static final String finalEncode(String plainText) {
DES3Tools des3 = new DES3Tools();
String garbleText = plainText + "|" + des3.getGarbleString(plainText);
return des3.base64Encode(des3.encrypt(garbleText));
}
/**
* 3des 通信最终解密工具
*
* @param garbeText
* @return
*/
public static final String finalDEcode(String garbeText) {
String plainText = null;
DES3Tools des3 = new DES3Tools();
byte[] tmpByte = des3.base64DEcode(garbeText);
String tmpString = des3.decrypt(tmpByte);
String[] tmpStrs = tmpString.split("\\|");
if (des3.verifyString(tmpStrs)) {
plainText = tmpStrs[0];
} else {
}
return plainText;
}
public static void main(String[] args) {
DES3Tools ed = new DES3Tools();
String plainText = "2217";
String garbleText = ed.getGarbleString(plainText);
System.err
.println("---------------------------------------------------------------------");
System.out.println("生成明文混淆字符串 :" + garbleText);
String[] strs = { plainText, garbleText };
System.out.println("验证混淆字符串是否正确 :" + ed.verifyString(strs));
byte[] temp = ed.encrypt(plainText + "|" + garbleText);
String s = ed.byteArr2HexStr(temp);
String newStr = ed.base64Encode(temp);
System.out.println("加密后:" + s);
System.out.println("解密后:" + ed.decrypt(ed.hexStr2ByteArr(s)));
System.out.println("base64混淆后:" + newStr);
System.out.println("base64混淆解密后:"
+ ed.byteArr2HexStr(ed.base64DEcode(newStr)));
System.err
.println("=============================================================================");
String pt = "2217";
System.err.println("3des 加密工具使用 API 明文: " + pt);
System.err.println("DES3Tools.finalEncode(明文参数字符串)结果:"
+ DES3Tools.finalEncode(pt));
String gt = "bclsmKghcNh1NLewhZFbLDl+9d2uTgHcXqA3fR4zrz8UHfg7nNzeHQ==";
System.err.println("3des 解密工具使用 API 密文: " + gt);
System.err.println("DES3Tools.finalDEcode(密文参数字符串)结果:"
+ DES3Tools.finalDEcode(gt));
}
}
package com.uninf.video.util.encryption;
import org.uninf.config.ConfigReader;
/**
* 加密解密配置文件
*
* @author zhangwei
*
*
* @time 2013-1-29 上午8:50:23
*
*/
public class EncryptConfig {
public static final String DES3_KEY = get("DES3_KEY");//替换你的密钥
public static final String DES3_IV = get("DES3_IV");//替换你的IV
private static String get(String name) {
return ConfigReader.getConfigReader().get(name);
}
}