1、做银行接口转换时使用des加密报错:
Given final block not properly padded
百度了解决办法是更改之前加密工具类中的的填充方式:
获取Cipher对象的时候一定要写成
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
不要写成
Cipher cipher = Cipher.getInstance("DES");
否则解密的时候会报错:
Given final block not properly padded;
2、填充方式改成Nopadding后接着解密又报错:Input length not multiple of 8 bytes:
javax.crypto.IllegalBlockSizeException: Input length not multiple of 8 bytes
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1039)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:1007)
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)
at com.hanweb.jxnxBank.util.DESUtil.encrypt(DESUtil.java:37)
at com.hanweb.jxnxBank.controller.DealController.nxAction(DealController.java:65)
百度了说是,输入的加密源数据不足8个字节,推测是加密的填充模式不对,于是更改之前的填充方式:
[修改前的模式]
public static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";
[修改后的模式]
public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding ";
但是报错又回到原来的“Given final block not properly padded”,正当无奈的时候,灵机一动想到一个办法:加密填充使用Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")
;,解密填充使用
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
最后问题完美解决!!!
轮番试了好几回才成功的~
最后附上des加密解密工具类代码:
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64;
public class DESUtil {
/** 安全密钥 */
private String keyData = "WK807001";
/**
* 加密
*
* @param dataSource
* @param password
* @return
*/
public static String encrypt(byte[] dataSource, String password) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
// Cipher对象实际完成加密操作
// Cipher cipher = Cipher.getInstance("DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// Cipher cipher = Cipher.getInstance("DES/ECB/ISO10126Padding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
// 正式执行加密操作
return Base64.encodeBase64String(cipher.doFinal(dataSource));
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param src
* @param password
* @return
* @throws Exception
*/
public static String decrypt(String src, String password) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// Cipher对象实际完成解密操作
// Cipher cipher = Cipher.getInstance("DES");
// Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
// 真正开始解密操作
return new String(cipher.doFinal(Base64.decodeBase64(src)));
}
}
调用示例:
String password = "WK807001";
//加密:dataSource为要加密内容
res2 = DESUtil.encrypt(dataSource, password);
//解密:res3为要解密内容
res4 = DESUtil.decrypt(res3, password);