AES hex 解密报 Given final block not properly padded 的解决方案

Given final block not properly padded 的解决方法

上游给了一串密文,告诉我用aes解密 (十六进制的那种) 然后怎么也解密不了,后来了解了下,

AES 加解密 有两种格式, 一种是 base64 的情况, 一种是 hex 的情况

于是在网上找了AES hex类型解密 的代码,

使用了hex解密方式去解密,结果解密方法报错  Given final block not properly padded 

这个错误有两种问题,

1 你的密钥不对 

2 填充位数不对, AES 密钥有16 ,24,32 等 位数的字节, 密钥有多少位就应该用多大的填充字节,比如密钥是32位,你这边用了16位的解密方式,

           // 密钥补位
            int plus= 16-key.length();        
            byte[] data = key.getBytes("utf-8");
            byte[] raw = new byte[16];
            byte[] plusbyte={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
            for(int i=0;i<16;i++)
            {
                if (data.length > i)
                    raw[i] = data[i];
                else
                    raw[i] = plusbyte[plus];
            }

这样就会报 Given final block not properly padded  (鉴于最终块未正确填充) 字面意思很清楚, 就是未正确填充,

将填充代码修改成

               // 密钥补位
                int plus= 32-key.length();            
                byte[] data = key.getBytes("utf-8");
                byte[] raw = new byte[32];
                
                byte[] plusbyte={ 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,0x06, 0x07, 0x09, 0x0d };    
                for(int i=0;i<32;i++)
                {
                    if (data.length > i)
                        raw[i] = data[i];
                    else
                        raw[i] = plusbyte[plus];
                }
就可以解决问题

最后贴上解密方面的代码,


	    /** 
	     * 解密
	     * @param String src 解密字符串 
	     * @param String key 密钥
	     * @return 解密后的字符串 
	     */  
	    public static String Decrypt(String src, String key) throws Exception {
	        try {
	            // 判断Key是否正确
	            if (key == null) {
	                System.out.print("Key为空null");
	                return null;
	            }
	 
	            // 密钥补位
	            int plus= 32-key.length();            
	            byte[] data = key.getBytes("utf-8");
	            byte[] raw = new byte[32];
	            
	            byte[] plusbyte={ 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,0x06, 0x07, 0x09, 0x0d };    
	            for(int i=0;i<32;i++)
	            {
	            	if (data.length > i)
	            		raw[i] = data[i];
	            	else
	            		raw[i] = plusbyte[plus];
	            }
	            
	            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
	            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
	            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
	            
	            //byte[] encrypted1 = new Base64().decode(src);//base64
	            byte[] encrypted1 = toByteArray(src);//十六进制
	            
	            try {
	                byte[] original = cipher.doFinal(encrypted1);
	                String originalString = new String(original,"utf-8");
	                return originalString;
	            } catch (Exception e) {
	                System.out.println(e.toString());
	                return null;
	            }
	        } catch (Exception ex) {
	            System.out.println(ex.toString());
	            return null;
	        }
	    }
	    
	    /** 
	     * 将byte[]转为各种进制的字符串 
	     * @param bytes byte[] 
	     * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 
	     * @return 转换后的字符串 
	     */  
	    public static String binary(byte[] bytes, int radix){  
	        return new BigInteger(1, bytes).toString(radix);	// 这里的1代表正数  
	    }
	    
	    /**
	     * 16进制的字符串表示转成字节数组
	     *
	     * @param hexString 16进制格式的字符串            
	     * @return 转换后的字节数组
	     **/
	    public static byte[] toByteArray(String hexString) {
	        if (hexString.isEmpty())
	            throw new IllegalArgumentException("this hexString must not be empty");
	 
	        hexString = hexString.toLowerCase();
	        final byte[] byteArray = new byte[hexString.length() / 2];
	        int k = 0;
	        for (int i = 0; i < byteArray.length; i++) {//因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
	            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
	            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
	            byteArray[i] = (byte) (high << 4 | low);
	            k += 2;
	        }
	        return byteArray;
	    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值