File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Security and the fly likes BadPaddingException using AES Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » Security
Bookmark "BadPaddingException using AES" Watch "BadPaddingException using AES" New topic
Author

BadPaddingException using AES

Nischint Ramesh
Greenhorn

Joined: May 18, 2011
Posts: 2
Hi All,
My Requirement : I have to encrypt a password entered in JPasswordField. After encryption store it in a file. Also I have to decrypt the password for some application purposes which shouldn't matter. I have to decrypt and get the password back is all.

I found the following code to be working :


I change the value of mode to decrypt and text to the encrypted string ( just copied and pasted from console ), the code works fine. No BadPaddingException whatsoever.
I have integrated the above class into my application ( without the main method of course ). Now I call encrypt and decrypt static methods.
Now when I do the following:

I get a BadPaddingException : Given final block not properly padded after the last code line. What could be the reason guys.? The first code with main class works fine (please let me know if it shouldn't).
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Your code for writing and reading the key is seriously flawed. You must close the key file when writing it and you cannot rely on the read() to read the whole of your key file when reading it. Read the Javadoc for InputStream.read(byte[] ) to see why. The safest way to read the file is to use DataInputStream.readFully(). For example -

Though failure of your read() to read the whole key could cause the BadPaddingException I have never seen this problem on a lightly loaded system.

The difficulty I had with your code is that you don't return the ciphertext or cleartext from your encrypt() and decrypt() methods yet you say your BadPaddingException occurs only when you do! After changing your code so it returns the cleartext/ciphertext I don't see your problem and don't get the BadPaddingException. There are three common causes of BadPaddingException. First if the key used is incorrect, second if the ciphertext is corrupted and third if you try to decrypt something that is not encrypted. From you test harness I suspect you are trying to decrypt something that has not been encrypted OR that your key is not being read or written propperly.

Note - it is considered insecure to encrypt and store passwords. It is normally better to use a randomly seeded hashing so that nobody can easily obtain the original password from the hashed password. Even if you do have to encrypt the passwords, it is not considered secure to use ECB mode (the mode you get by default) since it is open to fraud by splicing of ciphertext and more worryingly it will allow someone with access to the database to determine which people have the same password. You should use something like CBC mode with a random IV.


Retired horse trader.
 Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.
Nischint Ramesh
Greenhorn

Joined: May 18, 2011
Posts: 2
James Sabre wrote:Your code for writing and reading the key is seriously flawed. You must close the key file when writing it and you cannot rely on the read() to read the whole of your key file when reading it. Read the Javadoc for InputStream.read(byte[] ) to see why. The safest way to read the file is to use DataInputStream.readFully(). For example -

Though failure of your read() to read the whole key could cause the BadPaddingException I have never seen this problem on a lightly loaded system.

The difficulty I had with your code is that you don't return the ciphertext or cleartext from your encrypt() and decrypt() methods yet you say your BadPaddingException occurs only when you do! After changing your code so it returns the cleartext/ciphertext I don't see your problem and don't get the BadPaddingException. There are three common causes of BadPaddingException. First if the key used is incorrect, second if the ciphertext is corrupted and third if you try to decrypt something that is not encrypted. From you test harness I suspect you are trying to decrypt something that has not been encrypted OR that your key is not being read or written propperly.

Note - it is considered insecure to encrypt and store passwords. It is normally better to use a randomly seeded hashing so that nobody can easily obtain the original password from the hashed password. Even if you do have to encrypt the passwords, it is not considered secure to use ECB mode (the mode you get by default) since it is open to fraud by splicing of ciphertext and more worryingly it will allow someone with access to the database to determine which people have the same password. You should use something like CBC mode with a random IV.


Thanks a lot for your code for reading and writing keys. I shall surely use the method you suggested.

I found the problem of BadPaddingException. The application was truncating the ciphertext to 20 characters as it was a default length used in the app. Thing is , There is lots of code in between the encrypting, storing and decrypting logic above. I have just posted the logic that I thought the problem would exist.

About your note of using a one way hash algorithm for storing passwords, cannot be done in the case of my requirement, as there would be no prompting user for password and checking against the hash on the other end. I'm basically "sending the password of some machine to someone who doesn't know what his password is".

I shall look into CBC mode for block. I do not know what a IV is. Could you just guide me regarding CBC and random IV.?

Thanks a lot again.
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Nischint Ramesh wrote:
I found the problem of BadPaddingException. The application was truncating the ciphertext to 20 characters as it was a default length used in the app. Thing is , There is lots of code in between the encrypting, storing and decrypting logic above. I have just posted the logic that I thought the problem would exist.


Whenever I am writing encryption software I make sure I create a small subsystem that can be tested in isolation. The BIG-BANG approach to testing is pretty much always a receipt for wasting a load of time. It is a relatively trivial task to create a class to do this work for you and then to create a JUnit test that will give you 100% confidence that your encryption/decryption code is working before getting involved with the GUI. You would then know that if you received a BadPaddingException that your ciphertext was corrupt.

You would also have avoided this problem if you had stored in the key file a digest (SHA1, MD5 etc) of the bytes of the key together with the bytes of the key. That way you can check the validity of the key before using it.


About your note of using a one way hash algorithm for storing passwords, cannot be done in the case of my requirement, as there would be no prompting user for password and checking against the hash on the other end. I'm basically "sending the password of some machine to someone who doesn't know what his password is".


This indicates that you are using the wrong technology. If you are sending a password to somebody using this approach then you will have to send them the decryption key! Therefore you have just replace one security problem (sending the password) with an identical security problem (sending the decryption key). Are you now going to encrypt the key before sending it and then encrypt the key to that before sending that etc etc etc.

The proper solution is to use public key encryption and then you would encrypt the password with the recipients public key and only he can then decrypt it. This can be achieved using PGP/GPG or ssh or SFTP with very little effort on your part.

Why do you think you need to pass a password to somebody? You would do better to get your client to use SSH. Your 'client' would then send you his SSH public key and you would add him to the authorised_keys file. The added advantage of this is that you could trace his usage. If you need to use Java for him to communicate there are several free open source Java SSH libraries.


I shall look into CBC mode for block. I do not know what a IV is. Could you just guide me regarding CBC and random IV.?


Since you are using the wrong technology in the first place this is not really applicable. It does sound like you need to do some background reading. I suggest you spend some time with "Beginning Cryptography with Java" by David Hook published by Wrox.


Thanks a lot again.
 
 
subject: BadPaddingException using AES