使用DES加密报错Given final block not properly padded/Input length not multiple of 8 bytes的解决办法(亲测有效~)

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);
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Android开发中,如果出现"Given final block not properly padded. Such issues can arise if a bad key is used during decryption"报错,通常是因为解密的密钥和加密的密钥不一致。解决方法如下: 1.检查密钥是否正确:检查加密和解密时使用的密钥是否一致,如果不一致,需要将其修改为相同的密钥。 2.检查加密算法是否正确:检查加密和解密时使用的算法是否一致,如果不一致,需要将其修改为相同的算法。 3.检查数据是否正确:检查加密和解密的数据是否正确,如果不正确,需要重新生成正确的数据。 以下是一个示例代码,用于解决Android开发中出现"Given final block not properly padded. Such issues can arise if a bad key is used during decryption"报错的问题: ```java try { // 加密 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keySpec = new SecretKeySpec(encryToken.getBytes(), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(encryToken.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); byte[] encrypted = cipher.doFinal(plainText.getBytes()); // 解密 Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keySpec2 = new SecretKeySpec(encryToken.getBytes(), "AES"); IvParameterSpec ivSpec2 = new IvParameterSpec(encryToken.getBytes()); cipher2.init(Cipher.DECRYPT_MODE, keySpec2, ivSpec2); byte[] decrypted = cipher2.doFinal(encrypted); } catch (Exception e) { e.printStackTrace(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值