在进行Des解码时,出现异常,出错原因是
1对3DES加密报文进行Base64编码,
2然后转为String传输,
3接收到的Sring转为byte[],
4先进性Base64解码,(缺少这一步)
5再进行3DES解码,
改正为:
1对3DES加密报文进行Base64编码,
2然后转为String传输,
3接收到的Sring转为byte[],
4先进行Base64解码,
5再进行3DES解码,
在进行3DES加密时当最后一位不足64时会自动补上,导致解密时报错
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:989)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
贴出原工具类DesUtils
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
/**
* @author
* @date 2019/07/23
*/
public class DesUtils {
private final static Logger logger = LoggerFactory.getLogger(DesUtils.class);
/**
* 加密
*
* @param str byte[]
* @param password String
* @return byte[]
*/
public static String encrypt(String password, String str) {
try {
byte[] datasource = str.getBytes("UTF-8");
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
//创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
//Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
//现在,获取数据并加密 正式执行加密操作
//按单部分操作加密或解密数据,或者结束一个多部分操作
byte[] bytes = cipher.doFinal(datasource);
String result = Base64.encodeBase64String(bytes);
return result;
} catch (Throwable e) {
logger.error("DES 加密异常,详情:" + e.toString());
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param datasource byte[]
* @param password String
* @return byte[]
* @throws Exception
*/
public static String decrypt(String password,String encryptResult) throws Exception {
// byte[] strbytes = Base64.decodeBase64(encryptResult);
byte[] strbytes = encryptResult.getBytes();
// byte[] src = datas.getBytes();
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");//返回实现指定转换的 Cipher 对象
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
byte[] bytes = cipher.doFinal(strbytes);
String result = new String(bytes);
// String result = Base64.encodeBase64String(bytes);
return result;
}
}
贴出使用的测试
@Test
public void test07(){
Timestamp d = new Timestamp(System.currentTimeMillis());
long dateTime = d.getDateTime();
//待加密内容
String str = dateTime + "," + "15555987064"+"," + "/member/bill-history";
System.out.println("原文:"+str);
//密码,长度要是8的倍数
String password = "1234567887654321";
String encryptResult = DesUtils.encrypt(password, str);
System.out.println("加密后:"+ encryptResult);
//直接将如上内容解密
try {
String decryResult = DesUtils.decrypt(password, encryptResult);
System.out.println("解密后:"+decryResult);
} catch (Exception e1) {
e1.printStackTrace();
}
String url = "http://190.58.81.67/web-api/page/wid/account/wechat/login?token="+encryptResult+"&lang=zh_TW";
System.out.println("===request url =="+ url);
String results = HttpClientUtils.doGet(url);
System.out.println("===response==="+results);
}