• Post Reply Bookmark Topic Watch Topic
  • New Topic

Cipher BAdPaddingException  RSS feed

 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a jar file that I compiled maybe a year ago that uses Cipher and works fine (still does) and I have not needed to recompile it until now. The newly compiled code is suddenly giving me a BadPaddingException (using the exact same data). Rather than post a lot of code showing how all the data is used to generate the relevant strings, at this point I am just looking for an explanation of what that exception really means. The relevant code segment is:

Which parameter is not padded correctly (is it one of those passed to init or is it the one being passed to dofinal) and who/what does the padding? Since this area of code is untouched in the new version I have to assume this must be data dependent (although the data is the same for the working jar file) but how do I determine which piece of data? TIA.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ciphertext is binary data, you can't treat it like character data - and thus you can't convert it to a String (at least not without using base-64 encoding or something like it).
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whilst Ulf is correct in that ciphertext is binary data and cannot safely be converted to String without some form of encoding I don't think this is your problem since you seem to have used hex encoding on both the ciphertext and the key.

There is so much that it is missing in that code fragment that one cannot give a definitive reason for the problem BUT one standard reason for getting a bad padding exception is that one is actually using the wrong key! What does the method getSecretKey() do?

Note - it is normally a bad idea to not specify the character encoding when converting bytes to and from a String. Your code will use the platform default encoding so may give different results even for computers running the same operating system. It is normally better to use something like utf-8 for all and then there will be no machine dependency
 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies. So do I understand that you are saying the culprit is the first parameter of the init and somehow the padding is now messed up by my getSecretKey method? Here is getSecretKey:

That is also used to generate cipherKey and cipherText which is what gets stored in a file so those would be messed up too. The goal being obfuscation rather than security.

As for the encoding, it is not clear to me from the documentation, how to specify the algorithm. It looks like it is a parameter in the getInstance method but When I try to do that the hexToBinary method goes away (my IDE gives me an undefined error).

Obviously I am not understanding something.

That also means I have another problem, don't I? How do I determine what algorithm is being used in the working version (same machine and thus OS) and why did recompiling change that algorithm? The original data was encoded thus:

I know the encoding has to change to match but the data is already saved and I am not using the encryptor for this test.

P.S. What is up with that "I agree" thing that looks like a reply and is totally irrelevant?
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Putnam wrote:
As for the encoding, it is not clear to me from the documentation, how to specify the algorithm. It looks like it is a parameter in the getInstance method but When I try to do that the hexToBinary method goes away (my IDE gives me an undefined error).


Can you give us a pointer to the KeyGenerator class that you are using? ... because the one that is part of core java doesn't have a hextobinary method.

Henry
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Putnam wrote:So do I understand that you are saying the culprit is the first parameter of the init and somehow the padding is now messed up by my getSecretKey method?

No I'm not saying that. I'm saying that it is possible that the key you are generating in your latest version is not the same as in your original. That could be caused by some change to the getSecretKey() method but looking at the method I would be more inclined to believe that you have provided the wrong password.

Here is getSecretKey:

That is also used to generate cipherKey and cipherText which is what gets stored in a file so those would be messed up too. The goal being obfuscation rather than security.

As for the encoding, it is not clear to me from the documentation, how to specify the algorithm.



It looks like it is a parameter in the getInstance method but When I try to do that the hexToBinary method goes away (my IDE gives me an undefined error).

Obviously I am not understanding something.

Since you are trying to obfuscate it would make more sense to just create the file from the raw bytes without ever converting them to anything that is human readable.

That also means I have another problem, don't I? How do I determine what algorithm is being used in the working version (same machine and thus OS) and why did recompiling change that algorithm? The original data was encoded thus:


Apart from the dreadful exception handling implied by this code fragment and the exception handling shown in the decrypt method this looks OK.


I know the encoding has to change to match but the data is already saved and I am not using the encryptor for this test.

I really don't understand what you mean by this. I assumed you were trying to decrypt with your new code date encrypted with you old code so how exactly are you testing this. Maybe your test code is faulty!
 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks again for the reply. I guess I need to explain a few things to make clear where I'm coming from. This was my first Java application (written a few years ago) and among other things I was learning encryption. I've also not done much Java programming since so I guess I am still a relative beginner. However, I am not able to do a major rewrite at this time to clean up rookie code. The values involved are being read from a file which was generated a couple of years ago as part of user "registration" code. I tried just writing binary data to the file at that time and had all kinds of problems with various OS's so I settled on writing readable hex data (it also made debugging easier). The data was generated when the user input "registration" information. So the only time any of that gets encrypted/encoded is when new "registration" data is entered. Thus the read data has not changed in a couple of years. That is what I meant when I said encryption is not being used for this test. The bottom line is that I am stumped as to why the old jar file works on that data yet the newly compiled version does not. Since I don't really understand what the error is telling me or where to look, I can't figure out how to debug the problem. I don't want to make any radical changes, at least until I understand what is going on. The data has not changed, and the old jar file works with that data. As I see it there are 2 possibilities: 1) routine updates to the OS has changed the Cipher library which now wants something different but such a change, to make existing code incompatible, seems unlikely. 2) Something I did in unrelated classes (seems the most likely) is causing this problem but not understanding the error or what culprits to look at, are making it impossible to debug at this point.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In your position I would decompile your encryption classes in your old jar file to see if you have changed anything.

Note - DES is a block cipher and block ciphers can only encrypt a whole block of data at a time. To handle a partial block 'padding' is added to the block to make it's length the block size. Obviously when one decrypts a block one has to remove the padding or one does not get back the cleartext one encrypted. If on decrypting the decryption process finds that the padding does not conform to the specification for the padding then one has bad padding and an exception is thrown. The bad padding can result form any number of things but my experience is that most times it results from using the wrong decryption key. Now in your code there are several parameters that contribute to the key generation (salt, iteration count and password) and if any of these is wrong your key will be wrong.
 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah ha! I think I found it. The problem is not in the java code at all. Something is happening in the 'ant' compile step that is messing up a properties file. Sorry for the bother.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Putnam wrote:Ah ha! I think I found it. The problem is not in the java code at all. Something is happening in the 'ant' compile step that is messing up a properties file. Sorry for the bother.


Well done - but are you now going to fix the weaknesses I pointed out?
 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since I am working in the code, yes I should. The exception handling I know how to do, its specifying the encoding algorithm that I don't see how/where to do.
 
Richard Tookey
Bartender
Posts: 1166
17
Java Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Putnam wrote:o, its specifying the encoding algorithm that I don't see how/where to do.


I've shown you in an earlier response! You just specify "utf-8" (or whatever character encoding you decide to use) when doing the byte to String and String to byte conversions! Of course you won't use this with binary data will you?
 
Dennis Putnam
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Doh! Sorry.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!