import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;import com.sun.crypto.provider.SunJCE;public class CryptUtil {
private static String desAlgorithm = "DESede/CBC/PKCS5Padding";
private static String desKeyAlgorithm = "DESede";
private static byte defaultIV[] = { 1, 2, 3, 4, 5, 6, 7, 8 };



static {
try {
java.security.Security.addProvider(new SunJCE());
} catch (Exception e) {
throw new RuntimeException("加载SunJCE出错");
}
} /**
 * 
 * 生成密钥key对象
 * @param KeyStr 密钥字符串
 * @return 密钥对象
 * @throws InvalidKeyException 
 * @throws NoSuchAlgorithmException 
 * @throws InvalidKeySpecException 
 * @throws Exception
 */
private static Key KeyGenerator(String KeyStr) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
byte input[] = Hex.decode(KeyStr);
DESedeKeySpec KeySpec = new DESedeKeySpec(input);
SecretKeyFactory KeyFactory = SecretKeyFactory
.getInstance(desKeyAlgorithm);
return ((Key) (KeyFactory
.generateSecret(((java.security.spec.KeySpec) (KeySpec)))));
} /**
 * 
 * Des加密解密核心方法
 * @param input 需要加密或者解密的字节数组
 * @param key   密钥
 * @param algorithm 算法
 * @param cryptModel 加密模式 1加密 2解密
 * @param iv 加密向量 可以为空
 * @return 加密或者解密的字节数组
 */
public static byte[] cryptBy3Des(byte input[],String key,int cryptModel,byte iv[])
{
try {
Key k = KeyGenerator(key);
IvParameterSpec IVSpec = iv != null ? IvGenerator(iv)
: IvGenerator(defaultIV);
Cipher c = Cipher.getInstance(desAlgorithm);
c.init(cryptModel, k, ((java.security.spec.AlgorithmParameterSpec) (IVSpec)));
return c.doFinal(input);
} catch (InvalidKeyException e) {
throw new CryptException("无效的key:"+key+",错误的编码或者长度",e);
} catch (NoSuchAlgorithmException e) {
throw new CryptException("无效的算法:"+desAlgorithm,e);
} catch (NoSuchPaddingException e) {
throw new CryptException("无效的填充机制",e);
} catch (InvalidAlgorithmParameterException e) {
throw new CryptException("无效的算法:"+desAlgorithm,e);
} catch (IllegalBlockSizeException e) {
throw new CryptException("无法解密",e);
} catch (BadPaddingException e) {
throw new CryptException("无法解密",e);
} catch (InvalidKeySpecException e) {
throw new CryptException("无效的key:"+key+",错误的编码或者长度",e);

}
/**
 * 3DES加密
 * @param input 需要加密的内容
 * @param key   密钥
 * @return
 */
public static byte[] encryptBy3Des(byte input[],String key){
return cryptBy3Des(input, key,1,null);
}

/**
 * 将需要加密的字符串,首先按照指定编码转换成
 * 字节数组,然后进行3DES加密,最后进行Base64编码
 * 将加密后的内容, 按照指定的编码转换成字符串返回
 * @param content 需要加密的字符串
 * @param key            密钥
 * @param encoding       指定编码
 * @return
 */
public static String encryptBy3DesAndBase64(String content,String key,String encoding){
byte[] input;
try {
input = content.getBytes(encoding);
byte[] output = encryptBy3Des(input, key);
output = Base64.encode(output);
return new String(output, encoding);
} catch (UnsupportedEncodingException e) {
throw new CryptException("无效的编码:"+encoding,e);
}
}

/**
 * 将需要解密的字符串,首先按照指定编码转换成
 * 字节数组,然后进行Base64解码,最后进行3DES解密
 * 将解密的内容,按照指定的编码转换成字符串返回
 * @param encryptContent 需要解密的字符串
 * @param key            密钥
 * @param encoding       编码
 * @return
 */
public static String decryptBy3DesAndBase64(String encryptContent,String key,String encoding){
byte[] input;
try {
input = encryptContent.getBytes(encoding);
input = Base64.decode(input);
byte [] output = decryptBy3Des(input, key);
return new String(output, encoding);
} catch (UnsupportedEncodingException e) {
throw new CryptException("无效的编码:"+encoding,e);
}
}

/**
 * 3DES解密
 * @param input 需要解密的内容
 * @param key   密钥
 * @return
 */
public static byte[] decryptBy3Des(byte input[],String key){
return cryptBy3Des(input, key,2,null);
} private static IvParameterSpec IvGenerator(byte[] b)  {
IvParameterSpec IV = new IvParameterSpec(b);
return IV;
}
public static void main(String[] args) throws UnsupportedEncodingException {
String key  = "EA22DAB57022E2560A376749E3408196A9E287D800E068E8";
String key1 = "EA22DAB57022E2560A376749E3408196A9E287D800E068E9";
//这里使用48位的key
//然后把双数位的字符+1  那些这个 同样可以解密
//比如修改最后一位   EA22DAB57022E2560A376749E3408196A9E287D800E068E9 可以解密
//修改第二位置A为B EB22DBB57022E2560A376749E3408196A9E287D800E068E8 也可以解密
//同时把多个双数位的字符+1也可以解密
//比如修改第2位 第4位 第6位 EB23DBB57022E2560A376749E3408196A9E287D800E068E8
String s =encryptBy3DesAndBase64("www算法的ww杀毒啊是",key,"UTF-8");//加密
System.out.println(decryptBy3DesAndBase64(s, key1,"UTF-8"));//解密
//这种情况 我在别人公司写的3DES加密的类中 还有自己公司以前的3DES加密 也发现有这种情况
//我想确认一下 这种情况 到底正常不正常
}
}

解决方案 »

  1.   

    import org.bouncycastle.util.encoders.Base64;
    import org.bouncycastle.util.encoders.Hex;分析下这两个包中的东西,加解密算法上能回答你的这个问题
      

  2.   

        public static void main(String[] args) throws UnsupportedEncodingException {
            String key  = "EA22DAB57022E2560A376749E3408196A9E287D800E068E8";
            String key1 = "EA22DAB57022E2560A376749E3408196A9E287D800E068E9";
            //这里使用48位的key
            //然后把双数位的字符+1  那些这个 同样可以解密
            //比如修改最后一位   EA22DAB57022E2560A376749E3408196A9E287D800E068E9 可以解密
            //修改第二位置A为B EB22DBB57022E2560A376749E3408196A9E287D800E068E8 也可以解密
            //同时把多个双数位的字符+1也可以解密
            //比如修改第2位 第4位 第6位 EB23DBB57022E2560A376749E3408196A9E287D800E068E8

            String s =encryptBy3DesAndBase64("www算法的ww杀毒啊是",key,"UTF-8");//加密
            System.out.println(decryptBy3DesAndBase64(s, key1,"UTF-8"));//解密
            //这种情况 我在别人公司写的3DES加密的类中 还有自己公司以前的3DES加密 也发现有这种情况
            //我想确认一下 这种情况 到底正常不正常
        }