Hello I am trying to encrypt/decrypt using AES 128-bit key.
I still on getting the error: InvalidKeyException: Parameters missing at the line:
cipher.init( Cipher.DECRYPT_MODE, skeySpec );
I have googled the error and I'm aware of the following issues:
1) use "AES/CBC/PKCS5Padding" both when you encrypt and decrypt.
2) use UTF-8 when converting string to bytes
3) Convert the key and message to Base64 or HEX.
Any ideas what the problem can be? Thanks in advance.
1) Since you haven't published the exception stack trace and indicated which it the offending line one has to guess and I guess that your current problem is that your hex encode and decode methods are flawed. They are certainly over complicated and since you have not published the code for the method fromDigit() I can't be certain.
2) Since you are using CBC block mode, you have a future problem in that you don't pass the random IV generated in your encrypt() method to your decrypt() method. This will most probably show itself when you have fixed the first problem.
3) You have a potential problem in that you turn you cleartext string to bytes using utf-8 encoding but when converting back you use the default encoding which may or may not be utf-8. You may get away with this for a long time but one days it will jump up and bite you.
Retired horse trader.
Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.
Joined: Jan 07, 2004
Thanks for your help. The IV solved the problem
I created the IV and passed the IV over the network ("to BOB") as a HEX string.
byte IV = cipher.getIV ();
String IV = asHex( iv );
When decrypting I ("BOB") turn(s) the IV to a byte array and use the IV:
byte IV = hexFromString( iv );
cipher.init( Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec( IV ) );
Regarding turning the cleartext string into bytes using utf-8 I turned it back using:
String string = new String( original, "UTF-8");
I guess we ALWAYS have to send the IV to the reciever ("BOB"), when using AES? Or does that depends on the encryption mode, i.e. ECB, CBC, OCB. Is there any other encryption techniques, where don´t need to send an IV?
Interesting that the exception detail is so misleading; it implies that the Sun provider treats the IV as part of the key. Weird!
Any block mode that uses feedback (this means just about any block mode other than ECB) will need use some initialisation vector (IV). Ideally this IV should be different each time you do any encryption so letting the Cipher.init() method create a random IV is usually the best approach. This generated IV does not have to be kept secret so it is acceptable for it to be transmitted with the ciphertext in the clear. One common way of doing this is to add it as a prefix to the ciphertext.
ECB block mode is considered insecure since it admits splicing of ciphertext. All feedback modes that I am aware of do not admit splicing so you are much better off using one of the feedback modes. Using CBC puts you ahead of most of the field when posting encryption problems in this forum since most people use ECB. Sun JCE makes ECB the default which I consider a design flaw.
When passing ciphertext over some communication channel I dislike using Hex or Base65 or ASCII85 encoding and avoid it whenever possible. Using PKCS5 padding with AES will add between 1 and 16 bytes to the resultant cipher text. Pre-pending the IV will add 16 bytes. Hex encoding will double whatever you have so far. This seems a silly overhead unless one absolutely needs a human readable representation of ciphertet and for the most part one doesn't since the whole point of encryption is to make the result unreadable by humans.
Whether you are communicating over sockets or just writing the ciphertext to a file it is usually better to work with the raw ciphertext bytes. When encrypting multiple independent shortish cleartext over a single channel then using DataInputStream and DataOutputStream help. When encrypting large cleartext as one entity then CipherInputStream and CipherOutputStream are best BUT beware of the over tolerant error handling of these cipher streams.
Your change to to "utf-8" when recovering the String is correct.
P.S. I still dislike your Hex encoding methods. If you absolutely insist on writing your own rather than using one of the better free libraries (Google Jakarta commons codec) then you would do better using something like :-