import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
import com.sun.crypto.provider.SunJCE;
/**
* DESUtil工具类
*/
public class DESUtil {
private static String CodingType = "utf-8";
private static String CryptAlgorithm = "DESede/CBC/PKCS5Padding";
private static String KeyAlgorithm = "DESede";
private static byte defaultIV[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
public static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1',
(byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
(byte) '7', (byte) '8', (byte) '9', (byte) 'A', (byte) 'B',
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F' };
private static final int HMAC_NLENGTH = 16;
private static final Base64Encoder base64Encoder = new Base64Encoder();
@SuppressWarnings("unused")
private static final Base16Encoder base16Encoder= new Base16Encoder();
static {
try {
java.security.Security.addProvider(new SunJCE());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 3Des加密
* 调用者将需要加密的字符串传入该方法,方法内部首先对字符串转为UTF-8编码的字节数组
* 加密成功后,返回以Base64格式编码的字符串
* @param strTobeEnCrypted
* 需要加密的字符串
* @param strKey
* 加密密匙
* @param byteIV
* 加密向量
* @return 返回通过3Des加密后,以Base64编码的字符串
* @throws Exception
*/
public static String encrypt(String strTobeEnCrypted, String strKey,
byte byteIV[]) throws Exception {
byte input[] = strTobeEnCrypted.getBytes(CodingType);
Key k = keyGenerator(strKey);
IvParameterSpec IVSpec = byteIV.length != 0 ? IvGenerator(byteIV)
: IvGenerator(defaultIV);
Cipher c = Cipher.getInstance(CryptAlgorithm);
c.init(1, k, ((java.security.spec.AlgorithmParameterSpec) (IVSpec)));
byte output[] = c.doFinal(input);
return base64Encoder.encode(output);
//return new String(base64Encode(output), CodingType);
}
/**
* 转换3DES加密Key值
*
* @param KeyStr
* @return
* @throws Exception
*/
private static Key keyGenerator(String KeyStr) throws Exception {
byte input[] = Hex.decode(KeyStr);
DESedeKeySpec KeySpec = new DESedeKeySpec(input);
SecretKeyFactory KeyFactory = SecretKeyFactory
.getInstance(KeyAlgorithm);
return ((Key) (KeyFactory
.generateSecret(((java.security.spec.KeySpec) (KeySpec)))));
}
/**
* 3DES解密
* 调用者将需要解密的字符串传入该方法,方法内部首先对字符串转为Base64编码的字节数组。
* 解密成功后,返回通过Utf8编码的字符串
* @param strTobeDeCrypted
* 需要解密的已Base64编码的字符串
* @param strKey
* 解密密匙
* @param byteIV
* 加密向量
* @return 返回通过3Des解密后的以UTF-8格式编码的字符串
* @throws Exception
*/
public static String decrypt(String strTobeDeCrypted, String strKey,
byte byteIV[]) throws Exception {
//byte input[] = base64Decode(strTobeDeCrypted);
byte input[] = base64Encoder.decode(strTobeDeCrypted);
Key k = keyGenerator(strKey);
IvParameterSpec IVSpec = byteIV.length != 0 ? IvGenerator(byteIV)
: IvGenerator(defaultIV);
Cipher c = Cipher.getInstance(CryptAlgorithm);
c.init(2, k, ((java.security.spec.AlgorithmParameterSpec) (IVSpec)));
byte output[] = c.doFinal(input);
return new String(output, CodingType);
}
/**
* 3Des加密方法,返回字节数组
* 调用者调用该方法时,需要将需要加密的字符串转换为字节数组。
* 返回的字节数组,调用者可以进行编码返回不同的编码格式的字符串
* @param key 加密key
* @param iv 加密向量
* @param input 加密字节数组
* @return 返回加密后的字节数组
* @throws Exception
*/
public static byte[] originalEncrypt(String key, byte iv[], byte input[])
throws Exception {
Key k = keyGenerator(key);
IvParameterSpec IVSpec = iv.length != 0 ? IvGenerator(iv)
: IvGenerator(defaultIV);
Cipher c = Cipher.getInstance(CryptAlgorithm);
c.init(1, k, ((java.security.spec.AlgorithmParameterSpec) (IVSpec)));
return c.doFinal(input);
}
/**
* 3Des解密方法,返回字节数组
* 调用者调用该方法时,需要将需要解密的字符串转换为字节数组。
* 返回的字节数组,调用者可以进行编码返回不同的编码格式的字符串
* @param key
* @param iv
* @param input
* @return 将需要解密的字符串转换为字节数组
* @throws Exception
*/
public static byte[] originalDecrypt(String key, byte iv[], byte input[])
throws Exception {
Key k = keyGenerator(key);
IvParameterSpec IVSpec = iv.length != 0 ? IvGenerator(iv)
: IvGenerator(defaultIV);
Cipher c = Cipher.getInstance(CryptAlgorithm);
c.init(2, k, ((java.security.spec.AlgorithmParameterSpec) (IVSpec)));
return c.doFinal(input);
}
/**
* 将输入的Byte数组转换为以Base64格式编码的Byte数字
* @param b
* @return 以Base64格式编码的Byte数字
* @throws Exception
*/
public static byte[] base64Encode(byte b[]) throws Exception {
return Base64.encode(b);
}
/**
* 将以Base64编码的byte数组转换为普通Byte数组
* @param b
* @return 普通Byte数组
* @throws Exception
*/
public static byte[] base64Decode(byte b[]) throws Exception {
return Base64_EXT.decode(b);
}
/**
* 将Base64表示的字符串转换为byte数组
*
* @param s
* 使用Base64加密的字符串
* @return 进行Base64转换后得到的byte数组
* @throws Exception
*/
public static byte[] base64Decode(String s) throws Exception {
return Base64.decode(s);
}
/**
* 将Base64表示的字符串转换为byte数组
*
* @param str
* 使用Base64加密的字符串
* @return 进行Base64转换后得到的byte数组
* @throws Exception
*/
public static byte[] fromBase64String(String str) throws Exception {
return Base64_EXT.decode(str);
}
/**
* 将byte数组转化为用Base64表示的字符串
*
* @param buf
* 准备进行转化的byte数组
* @return 用Base64进行转化后得到的字符串
* @throws Exception
*/
public static String ToBase64String(byte[] buf) {
return new String(Base64.encode(buf));
}
/**
* 将Byte数组转换为utf-8格式的字符串
*
* @param buf
* 转变转换的byte数组
* @return 用utf-8格式编码的字符串
*/
public static String convertByteArrayToString(byte[] buf) {
try {
return new String(buf, CodingType);
} catch (Exception ex) {
return null;
}
}
/**
* 将字符串转换为utf-8格式的Byte数组
*
* @param str
* 需要转换的字符串
* @return utf-8格式的byte数组
*/
public static byte[] convertStringToByteArray(String str) {
try {
return str.getBytes(CodingType);
} catch (Exception ex) {
return null;
}
}
@SuppressWarnings("deprecation")
public static String urlEncode(String strToBeEncode) throws Exception {
return URLEncoder.encode(strToBeEncode);
}
@SuppressWarnings("deprecation")
public static String urlDecode(String strToBeDecode) throws Exception {
return URLDecoder.decode(strToBeDecode);
}
/**
* 将字符串用SHA1方式进行加密
*
* @param strTobeDigest
* 需要加密的字符串
* @return 用Base64编码加密后的字符串
*/
public static String GenerateDigest(String strTobeDigest) throws Exception {
byte input[] = strTobeDigest.getBytes(CodingType);
byte output[] = null;
MessageDigest DigestGenerator = MessageDigest.getInstance("SHA1");
DigestGenerator.update(input);
output = DigestGenerator.digest();
return new String(base64Encode(output));
}
/**
* 将字符串用MD5方式进行加密
*
* @param str
* 需要加密的字符串
* @return 用Base64编码加密后的字符串
*/
public static String md5Encry(String str) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
return new String(base64Encode(md.digest()));
}
private static IvParameterSpec IvGenerator(byte[] b) throws Exception {
IvParameterSpec IV = new IvParameterSpec(b);
return IV;
}
//创建HMACkey
public static SecretKey createHMACKey(){
try {
return RSAUtil.createKey("HmacSHA256");
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
//重获HMACkey
public static SecretKey retrieveHMACKey(String keyValue){
try {
SecretKey keya = new SecretKeySpec(hexString2Byte(keyValue),"HmacSHA256");
//get secret key.
return keya ;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
public static byte[] hexString2Byte(String s){
byte[] raw = s.getBytes();
byte[] hex = new byte[ raw.length/2];
for (int i=0;i<hex.length;i++) {
int leftBit4 = hexChar2int(raw[2*i]) << 4;
hex[i] = (byte)( leftBit4 | hexChar2int(raw[2*i+1]) );
}
return hex;
}
public static int hexChar2int(byte hexChar){
if( hexChar<HEX_CHAR_TABLE[10] ){
return hexChar-HEX_CHAR_TABLE[0];
}else{
return hexChar-HEX_CHAR_TABLE[10]+10;
}
}
public static SecretKey createKey(String algrithm)
throws NoSuchAlgorithmException {
KeyGenerator keyGen = null;
SecretKey key = null;
keyGen = KeyGenerator.getInstance(algrithm);
if (keyGen != null){
key = keyGen.generateKey();
}
return key;
}
public static String getKeyValue( SecretKey keya ){
String keys=null;
try {
byte[] ksba= keya.getEncoded();
keys= RSAUtil.toHexString(ksba);
return keys;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return keys;
}
public static String toHexString(byte[] raw)
throws UnsupportedEncodingException {
byte[] hex = new byte[2 * raw.length];
int index = 0;
for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
}
public static byte[] HMACSHA256_128(Key keySpec, byte[] src) {
return HMACSHA256_128(keySpec, src, HMAC_NLENGTH);
}
public static byte[] HMACSHA256_128(Key keySpec, byte[] src,int nLength) {
javax.crypto.Mac mac = null;
// SecretKey key=new SceretKey();
byte[] res = null;
try {
mac = javax.crypto.Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
mac.init(keySpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
// get 32 bytes HMACSHA256 result.
res = mac.doFinal(src);
// now truncate into nLength bytes HMACSHA256-128 result.
byte[] ret = new byte[nLength];
for (int i = 0; i < nLength; i++)
ret[i] = res[i];
return ret;
}
public static SecretKey createDESKey(){
try {
return AESUtil.createKey("DESede");
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static SecretKey retrieveDESKey(String keyValue){
try {
SecretKey keya = new SecretKeySpec(hexString2Byte(keyValue),"DESede");
//get secret key.
return keya ;
} catch (IllegalArgumentException e) {
// log.error("retrieveAESKey error, keyValue: " + keyValue, e );
// if( log.isDebugEnabled() ){
e.printStackTrace();
// }
return null;
}
}
public static String createDEScommonKey(){
SecretKey key = createDESKey();
String kv = getKeyValue( key );
System.out.println("DESKey:" + kv );
if(!kv.equals( getKeyValue(retrieveDESKey(kv)))){
System.out.println("wrong !" );
}
return kv;
}
/**
* @param args
*/
public static void main(String[] args) {
createDEScommonKey();
// try {
// System.out.println(DESUtil.encrypt("yinzj","EA22DAB57022E2560A376749E3408196A9E287D800E068E5",new byte[8]));
// System.out.println(DESUtil.decrypt("Pgmp5CCrhQY=","EA22DAB57022E2560A376749E3408196A9E287D800E068E5",new byte[8]));
// } catch (Exception ex) {
// ex.printStackTrace();
// }
//
//
// for( int i=0;i<32;i++ ){
// SecretKey key = createHMACKey();
// String kv = getKeyValue( key );
// System.out.println("HMACKey:" + kv );
// //SecretKey key2 = retireHMACKey(kv);
// if(!kv.equals( getKeyValue(retrieveHMACKey(kv)))){
// System.out.println("wrong !" );
// }
// }
}
}