javax.crypto.BadPaddingException:给定最终块未正确填充 [英] javax.crypto.BadPaddingException:Given final block not properly padded

查看:168
本文介绍了javax.crypto.BadPaddingException:给定最终块未正确填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在我的服务器上解密一个框架。加密帧来自客户端设备,通过套接字上的GPRS。加密使用 TripleDes 和给定的密钥完成。我在服务器端使用相同的算法和密钥。框架是Hex和Ascii String的组合。现在的问题是:当我使用零填充字节数组时,我得到以下异常。

I have to decrypt a frame on my server. Encrypted frame comes from client device through GPRS on socket.Encryption is done with TripleDes and with a given key.I use same algorithm and key on server side. Frame is a combination of Hex and Ascii String. Now the problem is : When I pad my byte array with zeros I get the following exception.

javax.crypto.BadPaddingException: Given final block not properly padded

以下是我的代码:

byte[] key = new byte[]{31, 30, 31, 36, 32, 11, 11, 11, 22, 26,
               30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
myKeySpec = new DESedeKeySpec(key);
mySecretKeyFactory = SecretKeyFactory.getInstance("TripleDES");
de = mySecretKeyFactory.generateSecret(myKeySpec);

    Cipher c = Cipher.getInstance("TripleDES");
c.init(Cipher.DECRYPT_MODE, key);

    int l = completeHexStr.length();

    if (l%8==1){
        completeHexStr = completeHexStr + "0000000";
    }else if (l%8==7){
        completeHexStr = completeHexStr + "0";
    }
byte decordedValue[] =completeHexString.getBytes();
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
System.out.println("decryptedValue= " + decryptedValue);

这是我在代码中使用的功能:

Here are the functions which I am using inside the code:

    public String stringToHex(String base) {
            StringBuffer buffer = new StringBuffer();
            int intValue = 0;
            for (int x = 0; x < base.length(); x++) {
                intValue = base.charAt(x);
                String hex = Integer.toHexString(intValue);
                if (hex.length() == 1) {
                    buffer.append("0" + hex + "");
                } else {
                    buffer.append(hex + "");
                }
            }
            return buffer.toString();
        }
    public String byteToAscii(byte[] b, int length) {
            String returnString = "";
            for (int i = 0; i < length; i++) {
                returnString += (char) (b[i] & 0xff);
            }
            return returnString;
        }

这是c中用于客户端加密的代码。 >

this is the code in c used for encryption at client side.

#include <svc_sec.h>
const unsigned char fixed_key[] = { 0x31, 0x30, 0x31, 0x36, 0x32, 0x11, 0x11, 0x11, 0x22, 0x26, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
int Comm_Encrypt_Data(unsigned char *Test_Input_Data, int Len_Input_Data)
{
int Count_Input_Data, Counter_Input_Data;
unsigned long Timer_1;
unsigned char Init_Vector[8];
int Counter_Init_Vector, Temp_Byte_Count;
unsigned char *Temp_Dst_Ptr, *Temp_Src_Ptr;
unsigned char Temp_Input_Frame[9], Temp_Output_Frame[9];
unsigned char Test_Output_Data[500];
unsigned char Test_Key_Arr[9];

memset(&Init_Vector[0], '\0', sizeof(Init_Vector));
memset(Test_Key_Arr, '0', sizeof(Test_Key_Arr));
memcpy(Test_Key_Arr, &fixed_key[0], 8);
Test_Key_Arr[sizeof(Test_Key_Arr)-1] = '\0';

Display_Data("KEY: ", Test_Key_Arr, sizeof(Test_Key_Arr)-1);

memset(Test_Output_Data, '\0', sizeof(Test_Output_Data));
memcpy(Test_Output_Data, Test_Input_Data, 48);

Count_Input_Data = Len_Input_Data -48 -3; //minus Data before payload, 3 bytes of '|' and CRC
Counter_Input_Data = 0;
while(Counter_Input_Data < Count_Input_Data)
{
Temp_Byte_Count = Count_Input_Data- Counter_Input_Data;
if(Temp_Byte_Count > 8)
Temp_Byte_Count = 8;

memcpy(Temp_Input_Frame, &Test_Input_Data[48+Counter_Input_Data], Temp_Byte_Count);
//succeeding bytes to be 0
if(Temp_Byte_Count < 8)
{
memset(&Temp_Input_Frame[Temp_Byte_Count], '0', (8-Temp_Byte_Count));

}

Display_Data("InPut Data Before Init",Temp_Input_Frame, Temp_Byte_Count);

//============Initialize the data
Temp_Dst_Ptr = (unsigned char *)Temp_Input_Frame;
Temp_Src_Ptr = (unsigned char *)&Init_Vector[0];
for(Counter_Init_Vector =0;Counter_Init_Vector < 8; Counter_Init_Vector++)
*Temp_Dst_Ptr++ ^= *Temp_Src_Ptr++;
//============Initializing data ends

DES(DESE, (unsigned char *)&Test_Key_Arr[0],
(unsigned char *)&Temp_Input_Frame[0], (unsigned char *)&Temp_Output_Frame[0]);
//DES(TDES3KE, (unsigned char *)&Test_Key_Arr[0],
// (unsigned char *)&Temp_Input_Frame[0], (unsigned char *)&Temp_Output_Frame[0]);
Display_Data("AFTER DES::::", Temp_Output_Frame, Temp_Byte_Count);

memcpy(&Test_Output_Data[48+Counter_Input_Data], Temp_Output_Frame, Temp_Byte_Count);
Counter_Input_Data += Temp_Byte_Count;

if(Counter_Input_Data < Count_Input_Data)
{
memcpy(Init_Vector, Temp_Output_Frame, 8);

}
}

{
memset(Test_Input_Data, '\0', Len_Input_Data);
memcpy(&Test_Input_Data[0], &Test_Output_Data[48], Counter_Input_Data); //1 Separator + 2 CRCs
}
Display_Data("Final Output Frame", Test_Input_Data, Counter_Input_Data);
return Counter_Input_Data;
}

我是新的java 加密。请告诉我怎么做?任何人都可以发布可以正常工作的代码来解密我的框架。谢谢提前。

I am new in java Cryptography. Please tell me how to do it? Can anybody post the code which can work properly to decrypt my frame. Thanks in advance.

推荐答案

您的代码的主要问题是您正在使用默认的PKCS5Padding进行解密。 TripleDES将导致TripleDES / ECB / PKCS5Padding内部。这是在Sun JCE提供商中实现的;大多数其他提供商复制此默认值。

The main issue with your code is that you are decrypting using a default of PKCS5Padding. "TripleDES" will result in "TripleDES/ECB/PKCS5Padding" internally. This is as it is implemented in the Sun JCE provider; most other providers copy this default.

似乎您期待零填充,这意味着您应该使用DESede / ECB / NoPadding code>之后,您可以使用外部函数来计算纯文本大小(如果不小心,则删除零填充可能会在最后删除零值纯文本)。

It seems you are expecting zero padding, which means you should use "DESede/ECB/NoPadding" instead. After that you can use an external function to calculate the plain text size (removing zero padding may remove zero valued plain text at the end if you are not careful).

其他问题:


  • 尝试在解密前填充数据(您应该 解密)

  • 编码和字符编码问题,例如尝试用0的字符值填充,这可能是错误的

  • trying to pad data before decryption (you should unpad data after decryption)
  • encoding and character encoding issues, such as trying to pad with the character value of "0", which is probably wrong

我已经指出ECB,因为我不知道使用实际模式。您可以使用正确的模式和填充算法修改您的问题,如果你能找到。如果ECB不起作用,您也可以尝试使用CBC模式。

I've indicated "ECB" because I don't know the actual mode used. You could amend your question with the right mode and padding algorithm if you can find out. You might want to try CBC mode as well if ECB does not work.

请注意,ECB模式除非特殊情况下使用是不安全的。使用CBC与随机IV是最低要求。

Note that ECB mode is not safe to use except for very specific circumstances. Using CBC with a randomized IV is a minimal requirement.

这篇关于javax.crypto.BadPaddingException:给定最终块未正确填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆